diff --git a/CMakeLists.txt b/CMakeLists.txt index 9842afc..d7cb53e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ # minimum CMake version required for C++20 support, among other things -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.18) # detect if Monocoque is being used as a sub-project of another CMake project if(NOT DEFINED PROJECT_NAME) @@ -37,10 +37,10 @@ add_executable(monocoque src/monocoque/monocoque.c) if(USE_PULSEAUDIO) message("Using pulseaudio backend...") add_compile_definitions(USE_PULSEAUDIO=true) - target_link_libraries(monocoque m hidapi-hidraw pulse serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir) + target_link_libraries(monocoque m hidapi-hidraw pulse serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir lua5.4) else() message("Using portaudio backend...") - target_link_libraries(monocoque m hidapi-hidraw portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir) + target_link_libraries(monocoque m hidapi-hidraw portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir lua5.4) endif() target_include_directories(monocoque PUBLIC config ${LIBXML_INCLUDE_DIR}) @@ -96,10 +96,10 @@ add_subdirectory(src/monocoque/slog) #target_link_libraries(hidtest hidapi-hidraw) #add_test(hidtest hidtest) # -#add_executable(simlighttest tests/simlighttest.c) -#target_include_directories(simlighttest PUBLIC) -#target_link_libraries(simlighttest serialport) -#add_test(simlighttest simlighttest) +add_executable(simlighttest tests/simlighttest.c) +target_include_directories(simlighttest PUBLIC) +target_link_libraries(simlighttest serialport) +add_test(simlighttest simlighttest) # used for enabling additional compiler options if supported diff --git a/src/monocoque/devices/CMakeLists.txt b/src/monocoque/devices/CMakeLists.txt index 8b70ff8..7b6e097 100644 --- a/src/monocoque/devices/CMakeLists.txt +++ b/src/monocoque/devices/CMakeLists.txt @@ -34,6 +34,8 @@ set(devices_source_files sound/usb_generic_shaker_pulse.c serial/arduino.h serial/arduino.c + serial/arduinoledlua.h + serial/arduinoledlua.c serial/moza.h serial/moza.c ) diff --git a/src/monocoque/devices/serial/arduino.c b/src/monocoque/devices/serial/arduino.c index a2c135e..f134ab8 100644 --- a/src/monocoque/devices/serial/arduino.c +++ b/src/monocoque/devices/serial/arduino.c @@ -2,13 +2,37 @@ #include #include #include +#include #include "arduino.h" +#include "arduinoledlua.h" #include "../serialadapter.h" #include "../../slog/slog.h" #define arduino_timeout 5000 +int arduino_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 arduino_update(SerialDevice* serialdevice, void* data, size_t size) { int result = 1; @@ -23,3 +47,285 @@ int arduino_init(SerialDevice* serialdevice, const char* portdev) serialdevice->id = monocoque_serial_open(serialdevice, portdev); return serialdevice->id; } + +int arduino_customled_init(SerialDevice* serialdevice, const char* portdev, const char* luafile) +{ + serialdevice->id = monocoque_serial_open(serialdevice, portdev); + + size_t bufsize1 = 11; + size_t recv_bufsize1 = 5; + char recv_buf1[recv_bufsize1]; + char bytes1[bufsize1]; + + for(int j = 0; j < bufsize1; j++) + { + bytes1[j] = 0x00; + } + bytes1[0] = 0xff; + bytes1[1] = 0xff; + bytes1[2] = 0xff; + bytes1[3] = 0xff; + bytes1[4] = 0xff; + bytes1[5] = 0xff; + bytes1[6] = 0x6c; + bytes1[7] = 0x65; + bytes1[8] = 0x64; + bytes1[9] = 0x73; + bytes1[10] = 0x63; + + int result = 0; + unsigned int timeout = 2000; + result = monocoque_serial_write_block(serialdevice->id, &bytes1, bufsize1, timeout); + result = monocoque_serial_read_block(serialdevice->id, &recv_buf1, recv_bufsize1, timeout); + //slogi("wrote %i bytes", result); + //sleep(2); + //monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevice->id]; + //result = arduino_check(sp_blocking_read(monocoque_serial_dev.port, &recv_buf1, recv_bufsize1, 5000)); + //slogi("read %i bytes", result); + //result = sp_blocking_read(serialdevice->port, &recv_buf1, recv_bufsize1, timeout); + + char numstr[recv_bufsize1]; + for(int j = 0; j < recv_bufsize1; j++) + { + numstr[j] = '\0'; + } + for(int j = 0; j < recv_bufsize1; j++) + { + if(recv_buf1[j] != 0 && recv_buf1[j] != 0x0d && recv_buf1[j] != 0x0a) + { + numstr[j] = recv_buf1[j]; + } + } + int numlights = atoi(numstr); + serialdevice->numleds = numlights; + slogi("numlights is %i\n", numlights); + + if(luafile == NULL) + { + return serialdevice->id; + } + + lua_State* L = luaL_newstate(); + luaL_openlibs(L); + + int top=lua_gettop(L); + int status = luaL_loadfile(L, luafile); + + if (status) { + /* If something went wrong, error message is at the top of */ + /* the stack */ + fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1)); + exit(1); + } + lua_setglobal(L,"myFunc"); + + serialdevice->L = L; + + return serialdevice->id; +} + + +int arduino_simled_update(SimDevice* this, SimData* simdata) +{ + SerialDevice* serialdevice = (void *) this->derived; + int result = 1; + + int total_leds = serialdevice->numleds; + size_t bufsize = (total_leds * 3) + 14; + char bytes[bufsize]; + int endled = serialdevice->endled; + int startled = serialdevice->startled; + if(endled == 0) + { + endled = total_leds; + } + int num_avail_leds = endled - startled + 1; + int rpm = simdata->rpms; + int maxrpm = simdata->maxrpm; + int litleds = 0; + if(rpm > 0 && maxrpm > 0) + { + int rpmmargin = ceil(.05*maxrpm); + int rpminterval = (maxrpm-rpmmargin) / (num_avail_leds); + + + for (int l = 1; l <= (num_avail_leds); l++) + { + if(rpm >= (rpminterval * l)) + { + litleds = l; + } + } + + + + for(int j = 0; j < bufsize; j++) + { + bytes[j] = 0x00; + } + bytes[0] = 0xff; + bytes[1] = 0xff; + bytes[2] = 0xff; + bytes[3] = 0xff; + bytes[4] = 0xff; + bytes[5] = 0xff; + bytes[6] = 0x73; + bytes[7] = 0x6c; + bytes[8] = 0x65; + bytes[9] = 0x64; + bytes[10] = 0x73; + bytes[bufsize-1] = 0xfd; + bytes[bufsize-2] = 0xfe; + bytes[bufsize-3] = 0xff; + + for(int i = 0; i < litleds; i++) + { + if(i < ((num_avail_leds) / 2)) + { + //green + bytes[11 + ((i + startled - 1) * 3) + 1] = 0xff; + } + else + { + if(i < num_avail_leds - 1) + { + //yellow + bytes[11 + ((i + startled - 1) * 3) + 0] = 0xff; + bytes[11 + ((i + startled - 1) * 3) + 1] = 0xff; + } + } + if(i == num_avail_leds - 1) + { + //red + bytes[11 + ((i + startled - 1) * 3) + 0] = 0xff; + } + } + } + + slogt("Updating arduino device lights to %i", litleds); + // we can add configs to set all the colors + size_t size = sizeof(bytes); + + result = monocoque_serial_write(serialdevice->id, &bytes, size, arduino_timeout); + + return result; +} + +int arduino_customled_update(SimDevice* this, SimData* simdata) +{ + SerialDevice* serialdevice = (void *) this->derived; + int result = 1; + + int total_leds = serialdevice->numleds; + size_t bufsize = (total_leds * 3) + 14; + char bytes[bufsize]; + + for(int j = 0; j < bufsize; j++) + { + bytes[j] = 0x00; + } + bytes[0] = 0xff; + bytes[1] = 0xff; + bytes[2] = 0xff; + bytes[3] = 0xff; + bytes[4] = 0xff; + bytes[5] = 0xff; + bytes[6] = 0x73; + bytes[7] = 0x6c; + bytes[8] = 0x65; + bytes[9] = 0x64; + bytes[10] = 0x73; + bytes[bufsize-1] = 0xfd; + bytes[bufsize-2] = 0xfe; + bytes[bufsize-3] = 0xff; + + + lua_State* L = serialdevice->L; + + lua_pushstring(L, "buff"); + lua_pushlightuserdata(L, &bytes); + lua_settable(L, LUA_REGISTRYINDEX); + + simdata_to_lua(L, simdata); + lua_setglobal(L, "simdata"); + + lua_pushinteger(L, total_leds); + lua_setglobal(L, "TotalLeds"); + + lua_register(L, "set_led_to_color", set_led_to_color); + lua_register(L, "set_led_range_to_color", set_led_range_to_color); + lua_register(L, "set_led_to_rgb_color", set_led_to_rgb_color); + lua_register(L, "set_led_range_to_rgb_color", set_led_range_to_rgb_color); + lua_register(L, "led_clear_all", led_clear_all); + + lua_pushinteger(L, LUALEDCOLOR_RED); + lua_setglobal(L, "RED"); + lua_pushinteger(L, LUALEDCOLOR_GREEN); + lua_setglobal(L, "GREEN"); + lua_pushinteger(L, LUALEDCOLOR_BLUE); + lua_setglobal(L, "BLUE"); + lua_pushinteger(L, LUALEDCOLOR_YELLOW); + lua_setglobal(L, "YELLOW"); + lua_pushinteger(L, LUALEDCOLOR_ORANGE); + lua_setglobal(L, "ORANGE"); + + lua_getglobal(L,"myFunc"); + if (lua_pcall(L, 0, 0, 0) != LUA_OK) + { + fprintf(stderr, "Error calling Lua script: %s\n", lua_tostring(L, -1)); + } + + size_t size = sizeof(bytes); + + arduino_update(serialdevice, &bytes, size); + + // move to free + + + + return result; +} + +int arduino_customled_free(SerialDevice* serialdevice, bool lua) +{ + size_t bufsize = (serialdevice->numleds * 3) + 14; + char bytes[bufsize]; + int endled = serialdevice->endled; + int startled = serialdevice->startled; + if(endled == 0) + + for(int j = 0; j < bufsize; j++) + { + bytes[j] = 0x00; + } + bytes[0] = 0xff; + bytes[1] = 0xff; + bytes[2] = 0xff; + bytes[3] = 0xff; + bytes[4] = 0xff; + bytes[5] = 0xff; + bytes[6] = 0x73; + bytes[7] = 0x6c; + bytes[8] = 0x65; + bytes[9] = 0x64; + bytes[10] = 0x73; + bytes[bufsize-1] = 0xfd; + bytes[bufsize-2] = 0xfe; + bytes[bufsize-3] = 0xff; + + for(int i = 0; i < serialdevice->numleds; i++) + { + bytes[11 + (i * 3) + 0] = 0x00; + bytes[11 + (i * 3) + 1] = 0x00; + bytes[11 + (i * 3) + 2] = 0x00; + } + size_t size = sizeof(bytes); + + int result = monocoque_serial_write(serialdevice->id, &bytes, size, arduino_timeout); + + if(lua == true) + { + lua_close(serialdevice->L); + } + return result; +} diff --git a/src/monocoque/devices/serial/arduino.h b/src/monocoque/devices/serial/arduino.h index 8bf47c9..29c6484 100644 --- a/src/monocoque/devices/serial/arduino.h +++ b/src/monocoque/devices/serial/arduino.h @@ -5,8 +5,12 @@ #include "../serialdevice.h" +int arduino_simled_update(SimDevice* this, SimData* simdata); int arduino_update(SerialDevice* serialdevice, void* data, size_t size); +int arduino_customled_init(SerialDevice* serialdevice, const char* portdev, const char* luafile); +int arduino_customled_update(SimDevice* this, SimData* simdata); int arduino_init(SerialDevice* serialdevice, const char* portdev); int arduino_free(SerialDevice* serialdevice); +int arduino_customled_free(SerialDevice* serialdevice, bool lua); #endif diff --git a/src/monocoque/devices/serial/arduinoledlua.c b/src/monocoque/devices/serial/arduinoledlua.c new file mode 100644 index 0000000..1b4210c --- /dev/null +++ b/src/monocoque/devices/serial/arduinoledlua.c @@ -0,0 +1,302 @@ +#include +#include +#include +#include +#include + +#include "arduinoledlua.h" +#include "arduino.h" + +#include "../../slog/slog.h" + + +int simdata_to_lua(lua_State *L, SimData* simdata) { + lua_newtable(L); + + lua_pushinteger(L, simdata->playerflag); + lua_setfield(L, -2, "playerflag"); + + lua_pushinteger(L, simdata->rpms); + lua_setfield(L, -2, "rpm"); + + lua_pushinteger(L, simdata->maxrpm); + lua_setfield(L, -2, "maxrpm"); + + return 1; // Return the table to Lua +} + +uint8_t get_color_rgb_value(int color, int rgb) +{ + switch (color) + { + case LUALEDCOLOR_RED: + switch (rgb) + { + case 0: + return 255; + case 1: + return 0; + case 2: + return 0; + } + case LUALEDCOLOR_GREEN: + switch (rgb) + { + case 0: + return 0; + case 1: + return 255; + case 2: + return 0; + } + case LUALEDCOLOR_BLUE: + switch (rgb) + { + case 0: + return 0; + case 1: + return 0; + case 2: + return 255; + } + case LUALEDCOLOR_YELLOW: + switch (rgb) + { + case 0: + return 255; + case 1: + return 255; + case 2: + return 0; + } + case LUALEDCOLOR_ORANGE: + switch (rgb) + { + case 0: + return 255; + case 1: + return 165; + case 2: + return 0; + } + default: + return 0; + } +} + +int set_led_range_to_color(lua_State *L) +{ + + slogt("lua called c function set_led_range_to_color"); + + int range_start = lua_tonumber(L, 1); + int range_end = lua_tonumber(L, 2); + int color = lua_tonumber(L, 3); + + slogd("lua range start is %i", range_start); + slogd("lua range end is %i", range_end); + slogd("lua color is %i", color); + + range_start = range_start - 1; + + lua_getglobal(L, "TotalLeds"); + int numlights = 0; + if (lua_isnumber(L, -1)) + { + numlights = lua_tonumber(L, -1); + } + slogd("num leds is %i", numlights); + + if(range_end > numlights) + { + range_end = numlights; + } + + if(range_end == 0) + { + slogt("Invalid range, doing nothing"); + return 1; + } + + lua_pushstring(L, "buff"); + lua_gettable(L, LUA_REGISTRYINDEX); + char* bytes = lua_touserdata(L, -1); + + slogt("tenth byte of buff is x%02x", bytes[10]); + + uint8_t color0 = get_color_rgb_value(color, 0); + uint8_t color1 = get_color_rgb_value(color, 1); + uint8_t color2 = get_color_rgb_value(color, 2); + + for( int i = range_start; i < range_end; i++) + { + bytes[(i * 3) + 11 + 0] = color0; + bytes[(i * 3) + 11 + 1] = color1; + bytes[(i * 3) + 11 + 2] = color2; + } + +} + +int set_led_range_to_rgb_color(lua_State *L) +{ + + slogt("lua called c function set_led_range_to_rgb_color"); + + int range_start = lua_tonumber(L, 1); + int range_end = lua_tonumber(L, 2); + int color0 = lua_tonumber(L, 3); + int color1 = lua_tonumber(L, 4); + int color2 = lua_tonumber(L, 5); + + slogd("lua range start is %i", range_start); + slogd("lua range end is %i", range_end); + slogd("lua color0 is %i", color0); + slogd("lua color1 is %i", color1); + slogd("lua color2 is %i", color2); + + range_start = range_start - 1; + + lua_getglobal(L, "TotalLeds"); + int numlights = 0; + if (lua_isnumber(L, -1)) + { + numlights = lua_tonumber(L, -1); + } + slogd("num leds is %i", numlights); + + if(range_end > numlights) + { + range_end = numlights; + } + + if(range_end == 0) + { + return 1; + } + + lua_pushstring(L, "buff"); + lua_gettable(L, LUA_REGISTRYINDEX); + char* bytes = lua_touserdata(L, -1); + + slogt("tenth byte of buff is x%02x", bytes[10]); + + for( int i = range_start; i < range_end; i++) + { + bytes[(i * 3) + 11 + 0] = color0; + bytes[(i * 3) + 11 + 1] = color1; + bytes[(i * 3) + 11 + 2] = color2; + } + +} + +int set_led_to_color(lua_State *L) +{ + slogt("lua called c function set_led_to_rgb_color"); + + int led = lua_tonumber(L, 1); + int color = lua_tonumber(L, 2); + + slogd("lua led is %i", led); + slogd("lua color is %i", color); + + led = led - 1; + + lua_getglobal(L, "TotalLeds"); + int numlights = 0; + if (lua_isnumber(L, -1)) + { + numlights = lua_tonumber(L, -1); + } + slogd("num leds is %i", numlights); + + if(led > numlights) + { + return 1; + } + + lua_pushstring(L, "buff"); + lua_gettable(L, LUA_REGISTRYINDEX); + char* bytes = lua_touserdata(L, -1); + + slogt("tenth byte of buff is x%02x", bytes[10]); + + uint8_t color0 = get_color_rgb_value(color, 0); + uint8_t color1 = get_color_rgb_value(color, 1); + uint8_t color2 = get_color_rgb_value(color, 2); + + bytes[(led * 3) + 11 + 0] = color0; + bytes[(led * 3) + 11 + 1] = color1; + bytes[(led * 3) + 11 + 2] = color2; + +} + + +int set_led_to_rgb_color(lua_State *L) +{ + slogt("lua called c function set_led_to_rgb_color"); + + int led = lua_tonumber(L, 1); + int color0 = lua_tonumber(L, 2); + int color1 = lua_tonumber(L, 3); + int color2 = lua_tonumber(L, 4); + + slogd("lua led is %i", led); + slogd("lua color0 is %i", color0); + slogd("lua color1 is %i", color1); + slogd("lua color2 is %i", color2); + + led = led - 1; + + lua_getglobal(L, "TotalLeds"); + int numlights = 0; + if (lua_isnumber(L, -1)) + { + numlights = lua_tonumber(L, -1); + } + slogd("num leds is %i", numlights); + + if(led > numlights) + { + return 1; + } + + lua_pushstring(L, "buff"); + lua_gettable(L, LUA_REGISTRYINDEX); + char* bytes = lua_touserdata(L, -1); + + slogt("tenth byte of buff is x%02x", bytes[10]); + + bytes[(led * 3) + 11 + 0] = color0; + bytes[(led * 3) + 11 + 1] = color1; + bytes[(led * 3) + 11 + 2] = color2; + +} + + +int led_clear_all(lua_State *L) +{ + + slogt("lua called c function led_clear_all"); + + lua_getglobal(L, "TotalLeds"); + int numlights = 0; + if (lua_isnumber(L, -1)) + { + numlights = lua_tonumber(L, -1); + } + slogd("num leds is %i", numlights); + + lua_pushstring(L, "buff"); + lua_gettable(L, LUA_REGISTRYINDEX); + char* bytes = lua_touserdata(L, -1); + + slogt("tenth byte of buff is x%02x", bytes[10]); + + for( int i = 0; i < numlights; i++) + { + bytes[(i * 3) + 11 + 0] = 0x00; + bytes[(i * 3) + 11 + 1] = 0x00; + bytes[(i * 3) + 11 + 2] = 0x00; + } + +} diff --git a/src/monocoque/devices/serial/arduinoledlua.h b/src/monocoque/devices/serial/arduinoledlua.h new file mode 100644 index 0000000..1e8061f --- /dev/null +++ b/src/monocoque/devices/serial/arduinoledlua.h @@ -0,0 +1,25 @@ +#ifndef _ARDUINOLEDLUA_H +#define _ARDUINOLEDLUA_H + +#include "lua5.4/lua.h" +#include "lua5.4/lauxlib.h" +#include "lua5.4/lualib.h" + +#include "../../simulatorapi/simapi/simapi/simdata.h" + +typedef enum { + LUALEDCOLOR_RED = 1, + LUALEDCOLOR_GREEN, + LUALEDCOLOR_BLUE, + LUALEDCOLOR_YELLOW, + LUALEDCOLOR_ORANGE, +} LUALEDColor; + +int simdata_to_lua(lua_State *L, SimData* simdata); +int set_led_range_to_color(lua_State *L); +int set_led_to_color(lua_State *L); +int set_led_range_to_rgb_color(lua_State *L); +int set_led_to_rgb_color(lua_State *L); +int led_clear_all(lua_State *L); + +#endif diff --git a/src/monocoque/devices/serialadapter.c b/src/monocoque/devices/serialadapter.c index e0a421f..c2f5fbe 100644 --- a/src/monocoque/devices/serialadapter.c +++ b/src/monocoque/devices/serialadapter.c @@ -128,6 +128,36 @@ int monocoque_serial_write_block(uint8_t serialdevicenum, void* data, size_t siz return result; } +int monocoque_serial_read_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_read(monocoque_serial_dev.port, data, size, timeout); + slogi("actually performed read"); + } + + monocoque_serial_dev.busy = false; + return result; +} + int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev) { int serial_device_num = -1; @@ -173,6 +203,7 @@ int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev) error = check(sp_get_port_by_name(port_name, &sp)); if (error != 0) { + sloge("Error opening serial port"); monocoque_serial_devices[i].open = false; monocoque_serial_devices[i].openfail = true; return -1; diff --git a/src/monocoque/devices/serialadapter.h b/src/monocoque/devices/serialadapter.h index bc023aa..fb021a1 100644 --- a/src/monocoque/devices/serialadapter.h +++ b/src/monocoque/devices/serialadapter.h @@ -22,6 +22,7 @@ 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_read_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); diff --git a/src/monocoque/devices/serialdevice.c b/src/monocoque/devices/serialdevice.c index d607396..1577c47 100644 --- a/src/monocoque/devices/serialdevice.c +++ b/src/monocoque/devices/serialdevice.c @@ -70,6 +70,8 @@ int arduino_shiftlights_update(SimDevice* this, SimData* simdata) return result; } + + int arduino_simwind_update(SimDevice* this, SimData* simdata) { SerialDevice* serialdevice = (void *) this->derived; @@ -151,6 +153,13 @@ int serialdev_free(SimDevice* this) size_t size = sizeof(SimHapticData); monocoque_serial_write_block(serialdevice->id, &serialdevice->u.simhapticdata, size, 9000); slogi("set zero to arduino device"); + break; + case ARDUINODEV__SIMLED__CUSTOM: + arduino_customled_free(serialdevice, true); + break; + case ARDUINODEV__SIMLED: + arduino_customled_free(serialdevice, false); + break; } @@ -181,17 +190,22 @@ int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds) serialdevice->motorsposition = ds->serialdevsettings.motorsposition; serialdevice->baudrate = ds->serialdevsettings.baud; - switch (serialdevice->type) + switch (serialdevice->devicetype) { - case SERIALDEV_WHEEL: - + case SERIALDEV__MOZAR5: // the wheel stuff assumed it was a usb //error = wheeldev_init(&serialdevice->u.wheeldevice, ds); + // maybe this call a more generic serial wheel init first error = moza_init(serialdevice, ds->serialdevsettings.portdev); break; - + case ARDUINODEV__SIMLED__CUSTOM: + error = arduino_customled_init(serialdevice, ds->serialdevsettings.portdev, ds->serialdevsettings.config_file); + break; + case ARDUINODEV__SIMLED: + error = arduino_customled_init(serialdevice, ds->serialdevsettings.portdev, NULL); + break; default: - error = arduino_init(serialdevice, ds->serialdevsettings.portdev ); + error = arduino_init(serialdevice, ds->serialdevsettings.portdev); break; } @@ -201,6 +215,8 @@ int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds) static const vtable serial_simdevice_vtable = { &serialdev_update, &serialdev_free }; static const vtable arduino_shiftlights_vtable = { &arduino_shiftlights_update, &serialdev_free }; +static const vtable arduino_simled_vtable = { &arduino_simled_update, &serialdev_free }; +static const vtable arduino_simled_custom_vtable = { &arduino_customled_update, &serialdev_free }; static const vtable arduino_simwind_vtable = { &arduino_simwind_update, &serialdev_free }; static const vtable arduino_simhaptic_vtable = { &arduino_simhaptic_update, &serialdev_free }; static const vtable serialwheel_vtable = { &serial_wheel_update, &serial_wheel_free }; @@ -223,6 +239,26 @@ SerialDevice* new_serial_device(DeviceSettings* ds, MonocoqueSettings* ms) { this->m.vtable = &arduino_shiftlights_vtable; slogi("Initializing arduino device for shiftlights."); break; + case (SIMDEVTYPE_SIMLED): + + if(ds->has_config == true) + { + this->devicetype = ARDUINODEV__SIMLED__CUSTOM; + this->startled = ds->serialdevsettings.startled; + this->endled = ds->serialdevsettings.endled; + this->m.vtable = &arduino_simled_custom_vtable; + slogi("Initializing arduino device for custom simled."); + } + else + { + this->devicetype = ARDUINODEV__SIMLED; + this->numleds = ds->serialdevsettings.numleds; + this->startled = ds->serialdevsettings.startled; + this->endled = ds->serialdevsettings.endled; + this->m.vtable = &arduino_simled_vtable; + slogi("Initializing arduino device for simled."); + } + break; case (SIMDEVTYPE_SIMWIND): this->devicetype = ARDUINODEV__SIMWIND; this->m.vtable = &arduino_simwind_vtable; diff --git a/src/monocoque/devices/serialdevice.h b/src/monocoque/devices/serialdevice.h index af7cbe1..e77ac27 100644 --- a/src/monocoque/devices/serialdevice.h +++ b/src/monocoque/devices/serialdevice.h @@ -10,6 +10,8 @@ typedef enum ARDUINODEV__SIMWIND = 1, ARDUINODEV__HAPTIC = 2, SERIALDEV__MOZAR5 = 3, + ARDUINODEV__SIMLED = 4, + ARDUINODEV__SIMLED__CUSTOM = 5 } SerialDeviceType; diff --git a/src/monocoque/devices/simdevice.h b/src/monocoque/devices/simdevice.h index 017a60b..339da3d 100644 --- a/src/monocoque/devices/simdevice.h +++ b/src/monocoque/devices/simdevice.h @@ -3,6 +3,8 @@ #include +#include "lua5.4/lua.h" + #include "usbdevice.h" #include "sounddevice.h" #include "serialdevice.h" @@ -49,10 +51,14 @@ typedef struct int id; SerialType type; struct sp_port* port; + lua_State* L; SerialDeviceType devicetype; // move these two they only apply to the haptic device int motorsposition; int numlights; + int numleds; + int startled; + int endled; int baudrate; double ampfactor; double state; diff --git a/src/monocoque/helper/confighelper.c b/src/monocoque/helper/confighelper.c index d0424cb..0b92409 100644 --- a/src/monocoque/helper/confighelper.c +++ b/src/monocoque/helper/confighelper.c @@ -145,6 +145,11 @@ int strtodevsubtype(const char* device_subtype, DeviceSettings* ds, int simdev) ds->dev_subtype = SIMDEVTYPE_SHIFTLIGHTS; break; } + if (strcicmp(device_subtype, "Simleds") == 0) + { + ds->dev_subtype = SIMDEVTYPE_SIMLED; + break; + } if (strcicmp(device_subtype, "SimWind") == 0) { ds->dev_subtype = SIMDEVTYPE_SIMWIND; @@ -748,6 +753,18 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co config_setting_lookup_int(device_settings, "numlights", &numlights); ds->serialdevsettings.numlights = numlights; + int numleds = 6; + config_setting_lookup_int(device_settings, "numleds", &numleds); + ds->serialdevsettings.numleds = numleds; + + int startled = 1; + config_setting_lookup_int(device_settings, "startled", &startled); + ds->serialdevsettings.startled = startled; + + int endled = 1; + config_setting_lookup_int(device_settings, "endled", &endled); + ds->serialdevsettings.endled = endled; + int baud = 9600; config_setting_lookup_int(device_settings, "baud", &baud); ds->serialdevsettings.baud = baud; @@ -758,6 +775,21 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co ds->serialdevsettings.ampfactor = ampfactor; slogt("set port baud rate to %i, ampfactor %f", baud, ampfactor); + + ds->has_config = false; + const char* temp2; + found = config_setting_lookup_string(device_settings, "config", &temp2); + slogt("config is %s found is %i", temp2, found); + if(strcicmp(temp2, "none") == 0) + { + slogt("config set to none"); + } + else + { + ds->has_config = true; + ds->serialdevsettings.config_file = strdup(temp2); + slogt("will try to load config file at %s", ds->serialdevsettings.config_file); + } } } @@ -827,7 +859,7 @@ int uiloadconfig(const char* config_file_str, int confignum, int configureddevic int settingsfree(DeviceSettings ds) { - if (ds.dev_subtype == SIMDEVTYPE_SIMWIND || ds.dev_subtype == SIMDEVTYPE_SHIFTLIGHTS) + if (ds.dev_subtype == SIMDEVTYPE_SIMWIND || ds.dev_subtype == SIMDEVTYPE_SHIFTLIGHTS || ds.dev_subtype == SIMDEVTYPE_SIMLED) { if (ds.serialdevsettings.portdev != NULL) { diff --git a/src/monocoque/helper/confighelper.h b/src/monocoque/helper/confighelper.h index 22cf3f2..2ef93bb 100644 --- a/src/monocoque/helper/confighelper.h +++ b/src/monocoque/helper/confighelper.h @@ -29,7 +29,8 @@ typedef enum SIMDEVTYPE_SIMWIND = 4, SIMDEVTYPE_SERIALHAPTIC = 5, SIMDEVTYPE_USBWHEEL = 6, - SIMDEVTYPE_SERIALWHEEL = 7 + SIMDEVTYPE_SERIALWHEEL = 7, + SIMDEVTYPE_SIMLED = 8 } DeviceSubType; @@ -153,8 +154,12 @@ TachometerSettings; typedef struct { char* portdev; + char* config_file; MotorPosition motorsposition; int numlights; + int numleds; + int startled; + int endled; float ampfactor; int baud; } @@ -195,6 +200,7 @@ typedef struct VibrationEffectType effect_type; MonocoqueTyreIdentifier tyre; double threshold; + bool has_config; // union? TachometerSettings tachsettings; SerialDeviceSettings serialdevsettings; diff --git a/tests/simlighttest.c b/tests/simlighttest.c index b228401..727b009 100644 --- a/tests/simlighttest.c +++ b/tests/simlighttest.c @@ -10,7 +10,7 @@ int check(enum sp_return result); int main() { - char* port_name = "/dev/ttyACM0"; + char* port_name = "/dev/simdev0"; /* The ports we will use. */ struct sp_port* port; @@ -32,39 +32,101 @@ int main() ShiftLightsData sd; - int result; - unsigned int timeout = 2000; - size_t size = sizeof(ShiftLightsData); - for( sd.litleds = 0; sd.litleds < 7; sd.litleds++) + + size_t bufsize1 = 11; + size_t recv_bufsize1 = 5; + char recv_buf1[recv_bufsize1]; + char bytes1[bufsize1]; + + for(int j = 0; j < bufsize1; j++) { + bytes1[j] = 0x00; + } + bytes1[0] = 0xff; + bytes1[1] = 0xff; + bytes1[2] = 0xff; + bytes1[3] = 0xff; + bytes1[4] = 0xff; + bytes1[5] = 0xff; + bytes1[6] = 0x6c; + bytes1[7] = 0x65; + bytes1[8] = 0x64; + bytes1[9] = 0x73; + bytes1[10] = 0x63; + + int result = 0; + unsigned int timeout = 2000; + result = check(sp_blocking_write(port, &bytes1, bufsize1, timeout)); + result = check(sp_blocking_read(port, &recv_buf1, recv_bufsize1, timeout)); + + char numstr[recv_bufsize1]; + for(int j = 0; j < recv_bufsize1; j++) + { + numstr[j] = '\0'; + } + for(int j = 0; j < recv_bufsize1; j++) + { + printf("%02x\n", recv_buf1[j]); + if(recv_buf1[j] != 0 && recv_buf1[j] != 0x0d && recv_buf1[j] != 0x0a) + { + numstr[j] = recv_buf1[j]; + } + } + int numlights = atoi(numstr); + printf("numlights is %s %i\n", numstr, numlights); + //printf("%x\n", recv_buf[0]); + //printf("%x\n", recv_buf[1]); + //printf("%x\n", recv_buf[2]); + //printf("%x\n", recv_buf[3]); + //printf("%x\n", recv_buf[4]); + + size_t bufsize = (numlights * 3) + 14; + char bytes[bufsize]; + for(int j = 0; j < bufsize; j++) + { + bytes[j] = 0x00; + } + bytes[0] = 0xff; + bytes[1] = 0xff; + bytes[2] = 0xff; + bytes[3] = 0xff; + bytes[4] = 0xff; + bytes[5] = 0xff; + bytes[6] = 0x73; + bytes[7] = 0x6c; + bytes[8] = 0x65; + bytes[9] = 0x64; + bytes[10] = 0x73; + bytes[bufsize-1] = 0xfd; + bytes[bufsize-2] = 0xfe; + bytes[bufsize-3] = 0xff; - - - /* On success, sp_blocking_write() and sp_blocking_read() - * return the number of bytes sent/received before the - * timeout expired. We'll store that result here. */ - - + for( int i = 0; i < numlights; i++) + { + bytes[(i * 3) + 11 + 1] = 0xff; /* Send data. */ - result = check(sp_blocking_write(port, &sd, size, timeout)); + result = check(sp_blocking_write(port, &bytes, bufsize, timeout)); /* Check whether we sent all of the data. */ - if (result == size) + if (result == bufsize) { - printf("Sent %d bytes successfully, %i lit leds.\n", size, sd.litleds); + printf("Sent %d bytes successfully, %i lit leds.\n", bufsize, numlights); } else { - printf("Timed out, %d/%d bytes sent.\n", result, size); + printf("Timed out, %d/%d bytes sent.\n", result, bufsize); } sleep(2); } - sd.litleds = 0; - result = check(sp_blocking_write(port, &sd, size, timeout)); + for( int i = 0; i < numlights; i++) + { + bytes[(i * 3) + 11 + 1] = 0x00; + } + result = check(sp_blocking_write(port, &bytes, bufsize, timeout)); check(sp_close(port)); sp_free_port(port);