diff --git a/src/monocoque/devices/serial/arduino.c b/src/monocoque/devices/serial/arduino.c index fc16dba..765ff74 100644 --- a/src/monocoque/devices/serial/arduino.c +++ b/src/monocoque/devices/serial/arduino.c @@ -42,63 +42,111 @@ int arduino_update(SerialDevice* serialdevice, void* data, size_t size) return result; } +// the input event waiting and flushing is the right way to do this +// most of the time i'm just "bit blasting" and the only receiving +// happens initially to get the number of lights +int GetNumberOfLeds(SerialDevice* serialdevice, int* numlights) + +{ + int count = 0; + int bytesWaiting; + char buf[256]; + int retval = 0; + int i; + + //sp_flush(port, SP_BUF_INPUT); + + while (count < 4) + { + slogi("Attempting to retrieve num lights from port..."); + + 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 = 6000; + slogd("Sending message to get num lights"); + monocoque_wait_for_event(serialdevice->id, 6); + + result = monocoque_serial_write(serialdevice->id, &bytes1, bufsize1, arduino_timeout); + + + monocoque_wait_for_event(serialdevice->id, 5); + bytesWaiting = monocoque_input_wait(serialdevice->id); + if (bytesWaiting > 0) + { + memset(buf, 0, sizeof(buf)); + retval = monocoque_serial_read_block(serialdevice->id, buf, sizeof(buf)-1, 10); + if (retval < 0) + { + retval = -1; + break; + } + else + { + for(i=0; iid = 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 numlights = 0; - int result = 0; - unsigned int timeout = 3000; - 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); + monocoque_serial_device serialdev = monocoque_serial_devices[serialdevice->id]; + int error = GetNumberOfLeds(serialdevice, &numlights); - 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); + // close, error and free if numlights is 0 + serialdevice->numleds = numlights; if(luafile == NULL) { diff --git a/src/monocoque/devices/serialadapter.c b/src/monocoque/devices/serialadapter.c index 1e5b6fd..d092ba7 100644 --- a/src/monocoque/devices/serialadapter.c +++ b/src/monocoque/devices/serialadapter.c @@ -73,6 +73,47 @@ int monocoque_serial_free(SerialDevice* serialdevice) } } + +int monocoque_wait_for_event(uint8_t serialdevicenum, int event) +{ + + slogt("serial device id %i", serialdevicenum); + monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevicenum]; + + int retval; + struct sp_event_set* eventSet = NULL; + + retval = sp_new_event_set(&eventSet); + if (retval == SP_OK) + { + retval = sp_add_port_events(eventSet, monocoque_serial_dev.port, event); + if (retval == SP_OK) + { + slogd("set event on port"); + retval = sp_wait(eventSet, 5000); + } + else + { + sloge("Unable to add events to port."); + retval = -1; + } + } + else + { + sloge("Unable to create new event set."); + retval = -1; + } + sp_free_event_set(eventSet); + + return retval; +} + +int monocoque_input_wait(uint8_t serialdevicenum) +{ + monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevicenum]; + return sp_input_waiting(monocoque_serial_dev.port); +} + int monocoque_serial_write(uint8_t serialdevicenum, void* data, size_t size, int timeout) { slogt("serial device id %i", serialdevicenum); @@ -216,7 +257,7 @@ int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev) } slogd("Opening port"); - check(sp_open(sp, SP_MODE_READ_WRITE)); + check(sp_open(sp, SP_MODE_READ | SP_MODE_WRITE)); slogd("Setting port to %i 8N1, no flow control", serialdevice->baudrate); check(sp_set_baudrate(sp, serialdevice->baudrate)); @@ -225,6 +266,9 @@ int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev) check(sp_set_stopbits(sp, 1)); check(sp_set_flowcontrol(sp, SP_FLOWCONTROL_NONE)); + check(sp_set_rts(sp, 1)); + check(sp_set_dtr(sp, 1)); + monocoque_serial_devices[i].port = sp; monocoque_serial_devices[i].open = true; diff --git a/src/monocoque/devices/serialadapter.h b/src/monocoque/devices/serialadapter.h index 6955891..67653ad 100644 --- a/src/monocoque/devices/serialadapter.h +++ b/src/monocoque/devices/serialadapter.h @@ -20,6 +20,8 @@ monocoque_serial_device; static monocoque_serial_device monocoque_serial_devices[20]; +int monocoque_input_wait(uint8_t serialdevicenum); +int monocoque_wait_for_event(uint8_t serialdevicenum, int event); 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); diff --git a/tests/simlighttest.c b/tests/simlighttest.c index c4330b4..346587e 100644 --- a/tests/simlighttest.c +++ b/tests/simlighttest.c @@ -1,16 +1,163 @@ #include #include #include +#include #include #include "../src/arduino/shiftlights/shiftlights.h" /* Helper function for error handling. */ -int check(enum sp_return result); +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"); + abort(); + case SP_ERR_FAIL: + error_message = sp_last_error_message(); + printf("Error: Failed: %s\n", error_message); + sp_free_error_message(error_message); + abort(); + case SP_ERR_SUPP: + printf("Error: Not supported.\n"); + abort(); + case SP_ERR_MEM: + printf("Error: Couldn't allocate memory.\n"); + abort(); + case SP_OK: + default: + return result; + } +} + + +int WaitForEventOnPort(struct sp_port* port, int event) +{ + int retval; + struct sp_event_set* eventSet = NULL; + + retval = sp_new_event_set(&eventSet); + if (retval == SP_OK) + { + retval = sp_add_port_events(eventSet, port, event); + if (retval == SP_OK) + { + printf("set event on port\n"); + retval = sp_wait(eventSet, 5000); + } + else + { + puts("Unable to add events to port."); + retval = -1; + } + } + else + { + puts("Unable to create new event set."); + retval = -1; + } + sp_free_event_set(eventSet); + + return retval; +} + +// the input event waiting and flushing is the right way to do this +// most of the time i'm just "bit blasting" and the only receiving +// happens initially to get the number of lights +int ReadFromPort(struct sp_port* port, int* numlights) +{ + int count = 0; + int bytesWaiting; + char buf[256]; + int retval = 0; + int i; + + sp_flush(port, SP_BUF_INPUT); + + while (count < 4) + { + printf("Attempting to retrieve num lights from port...\n"); + + 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 = 6000; + printf("Sending message to get num lights\n"); + WaitForEventOnPort(port, 6); + + result = check(sp_blocking_write(port, &bytes1, bufsize1, timeout)); + + printf("Attempting to receive response\n"); + + + WaitForEventOnPort(port, 5); + bytesWaiting = sp_input_waiting(port); + if (bytesWaiting > 0) + { + memset(buf, 0, sizeof(buf)); + //printf("bytes found on port\n"); + retval = sp_blocking_read(port, buf, sizeof(buf)-1, 10); + if (retval < 0) + { + printf("Error reading from serial port: %d\r\n", retval); + retval = -1; + break; + } + else + { + for(i=0; i