Add support for simhub protocol and custom lua scripts to control leds
This commit is contained in:
parent
d0f4a48c35
commit
9c0cadffdf
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,13 +2,37 @@
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,15 +190,20 @@ 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);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ typedef enum
|
|||
ARDUINODEV__SIMWIND = 1,
|
||||
ARDUINODEV__HAPTIC = 2,
|
||||
SERIALDEV__MOZAR5 = 3,
|
||||
ARDUINODEV__SIMLED = 4,
|
||||
ARDUINODEV__SIMLED__CUSTOM = 5
|
||||
}
|
||||
SerialDeviceType;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue