firmata: Convert mraa FirmataC implementation to work over Uart instead of serial implementation
Signed-off-by: Shiran Ben-Melech <shiran.ben-melech@intel.com> Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
committed by
Brendan Le Foll
parent
4b76fbd14c
commit
04f7cbff5d
@@ -24,7 +24,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "serial.h"
|
||||
#include "uart.h"
|
||||
|
||||
#define MODE_INPUT 0x00
|
||||
#define MODE_OUTPUT 0x01
|
||||
@@ -89,7 +89,7 @@ typedef struct s_pin {
|
||||
} t_pin;
|
||||
|
||||
typedef struct s_firmata {
|
||||
t_serial* serial;
|
||||
mraa_uart_context uart;
|
||||
t_pin pins[128];
|
||||
int i2cmsg[256][256];
|
||||
int parse_command_len;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
* Copyright (c) 2015 Jules Dourlens (jdourlens@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <termios.h>
|
||||
|
||||
typedef struct s_serial {
|
||||
int port_is_open;
|
||||
const char* port_name;
|
||||
int baud_rate;
|
||||
char* error_msg;
|
||||
|
||||
int port_fd;
|
||||
struct termios settings_orig;
|
||||
struct termios settings;
|
||||
int tx;
|
||||
int rx;
|
||||
} t_serial;
|
||||
|
||||
t_serial* serial_new();
|
||||
int serial_open(t_serial* serial, const char* name);
|
||||
int serial_setBaud(t_serial* serial, int baud);
|
||||
int serial_read(t_serial* serial, void* ptr, int count);
|
||||
int serial_write(t_serial* serial, void* ptr, int len);
|
||||
int serial_waitInput(t_serial* serial, int msec);
|
||||
int serial_discardInput(t_serial* serial);
|
||||
void serial_flushOutput(t_serial* serial);
|
||||
int serial_setControl(t_serial* serial, int dtr, int rts);
|
||||
@@ -3,7 +3,6 @@ if (FIRMATA)
|
||||
set (mraa_LIB_PLAT_SRCS_NOAUTO ${mraa_LIB_PLAT_SRCS_NOAUTO}
|
||||
${PROJECT_SOURCE_DIR}/src/firmata/firmata.c
|
||||
${PROJECT_SOURCE_DIR}/src/firmata/servo.c
|
||||
${PROJECT_SOURCE_DIR}/src/firmata/serial.c
|
||||
${PROJECT_SOURCE_DIR}/src/firmata/firmata_mraa.c
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "firmata/serial.h"
|
||||
#include "firmata/firmata.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -33,6 +32,7 @@ t_firmata*
|
||||
firmata_new(const char* name)
|
||||
{
|
||||
t_firmata* res;
|
||||
mraa_result_t uart_res = MRAA_ERROR_UNSPECIFIED;
|
||||
|
||||
printf("Opening device at: %s\n", name);
|
||||
res = malloc(sizeof(t_firmata));
|
||||
@@ -41,14 +41,20 @@ firmata_new(const char* name)
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof(*res));
|
||||
res->serial = serial_new();
|
||||
if (!res->serial) {
|
||||
perror("firmata_new::Failed malloc");
|
||||
return (NULL);
|
||||
|
||||
res->uart = mraa_uart_init_raw(name);
|
||||
if (res->uart == NULL) {
|
||||
fprintf(stderr, "UART failed to setup\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
serial_open(res->serial, name);
|
||||
|
||||
firmata_initPins(res);
|
||||
serial_setBaud(res->serial, 57600);
|
||||
|
||||
uart_res = mraa_uart_set_baudrate(res->uart, 57600);
|
||||
if (uart_res != MRAA_SUCCESS) {
|
||||
mraa_result_print(uart_res);
|
||||
}
|
||||
|
||||
firmata_askFirmware(res);
|
||||
printf("Device opened at: %s\n", name);
|
||||
return (res);
|
||||
@@ -60,9 +66,9 @@ firmata_pull(t_firmata* firmata)
|
||||
uint8_t buff[FIRMATA_MSG_LEN];
|
||||
int r;
|
||||
|
||||
r = serial_waitInput(firmata->serial, 40);
|
||||
r = mraa_uart_data_available(firmata->uart, 40);
|
||||
if (r > 0) {
|
||||
r = serial_read(firmata->serial, buff, sizeof(buff));
|
||||
r = mraa_uart_read(firmata->uart, buff, sizeof(buff));
|
||||
if (r < 0) {
|
||||
return (0);
|
||||
}
|
||||
@@ -178,7 +184,7 @@ firmata_endParse(t_firmata* firmata)
|
||||
buf[len++] = 1;
|
||||
}
|
||||
firmata->isReady = 1;
|
||||
serial_write(firmata->serial, buf, len);
|
||||
mraa_uart_write(firmata->uart, buf, len);
|
||||
} else if (firmata->parse_buff[1] == FIRMATA_CAPABILITY_RESPONSE) {
|
||||
int pin, i, n;
|
||||
for (pin = 0; pin < 128; pin++) {
|
||||
@@ -206,7 +212,7 @@ firmata_endParse(t_firmata* firmata)
|
||||
buf[len++] = pin;
|
||||
buf[len++] = FIRMATA_END_SYSEX;
|
||||
}
|
||||
serial_write(firmata->serial, buf, len);
|
||||
mraa_uart_write(firmata->uart, buf, len);
|
||||
}
|
||||
} else if (firmata->parse_buff[1] == FIRMATA_ANALOG_MAPPING_RESPONSE) {
|
||||
int pin = 0;
|
||||
@@ -228,12 +234,12 @@ firmata_endParse(t_firmata* firmata)
|
||||
printf("got an i2c reply with count %d!!\n", firmata->parse_count);
|
||||
int addr = (firmata->parse_buff[2] & 0x7f) | ((firmata->parse_buff[3] & 0x7f) << 7);
|
||||
int reg = (firmata->parse_buff[4] & 0x7f) | ((firmata->parse_buff[5] & 0x7f) << 7);
|
||||
int i = 6;
|
||||
int ii = 0;
|
||||
for (ii; ii < (firmata->parse_count - 7) / 2; ii++) {
|
||||
firmata->i2cmsg[addr][reg+ii] = (firmata->parse_buff[i] & 0x7f) | ((firmata->parse_buff[i+1] & 0x7f) << 7);;
|
||||
i = i+2;
|
||||
}
|
||||
int i = 6;
|
||||
int ii = 0;
|
||||
for (ii; ii < (firmata->parse_count - 7) / 2; ii++) {
|
||||
firmata->i2cmsg[addr][reg+ii] = (firmata->parse_buff[i] & 0x7f) | ((firmata->parse_buff[i+1] & 0x7f) << 7);;
|
||||
i = i+2;
|
||||
}
|
||||
printf("i2c reply is %d\n", firmata->i2cmsg[addr][reg]);
|
||||
}
|
||||
return;
|
||||
@@ -265,7 +271,7 @@ firmata_askFirmware(t_firmata* firmata)
|
||||
buf[0] = FIRMATA_START_SYSEX;
|
||||
buf[1] = FIRMATA_REPORT_FIRMWARE; // read firmata name & version
|
||||
buf[2] = FIRMATA_END_SYSEX;
|
||||
res = serial_write(firmata->serial, buf, 3);
|
||||
res = mraa_uart_write(firmata->uart, buf, 3);
|
||||
return (res);
|
||||
}
|
||||
|
||||
@@ -280,7 +286,7 @@ firmata_pinMode(t_firmata* firmata, int pin, int mode)
|
||||
buff[1] = pin;
|
||||
buff[2] = mode;
|
||||
printf("Setting pinMode at: %i with value: %i\n", pin, mode);
|
||||
res = serial_write(firmata->serial, buff, 3);
|
||||
res = mraa_uart_write(firmata->uart, buff, 3);
|
||||
return (res);
|
||||
}
|
||||
|
||||
@@ -294,7 +300,7 @@ firmata_analogWrite(t_firmata* firmata, int pin, int value)
|
||||
buff[0] = 0xE0 | pin;
|
||||
buff[1] = value & 0x7F;
|
||||
buff[2] = (value >> 7) & 0x7F;
|
||||
res = serial_write(firmata->serial, buff, 3);
|
||||
res = mraa_uart_write(firmata->uart, buff, 3);
|
||||
return (res);
|
||||
}
|
||||
|
||||
@@ -308,7 +314,7 @@ firmata_analogRead(t_firmata *firmata, int pin)
|
||||
buff[0] = FIRMATA_REPORT_ANALOG | pin;
|
||||
buff[1] = value;
|
||||
printf("192 == %d, pinval == %d, pin %d", buff[0], buff[1], pin);
|
||||
res = serial_write(firmata->serial, buff, 2);
|
||||
res = mraa_uart_write(firmata->uart, buff, 2);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -336,6 +342,6 @@ firmata_digitalWrite(t_firmata* firmata, int pin, int value)
|
||||
buff[0] = FIRMATA_DIGITAL_MESSAGE | port_num;
|
||||
buff[1] = port_val & 0x7F;
|
||||
buff[2] = (port_val >> 7) & 0x7F;
|
||||
res = serial_write(firmata->serial, buff, 3);
|
||||
res = mraa_uart_write(firmata->uart, buff, 3);
|
||||
return (res);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "mraa_internal.h"
|
||||
#include "firmata/firmata_mraa.h"
|
||||
#include "firmata/firmata.h"
|
||||
#include "firmata/serial.h"
|
||||
|
||||
static t_firmata* firmata_dev;
|
||||
static pthread_t thread_id;
|
||||
@@ -43,7 +42,7 @@ mraa_firmata_i2c_init_bus_replace(mraa_i2c_context dev)
|
||||
buff[1] = FIRMATA_I2C_CONFIG;
|
||||
buff[2] = delay & 0xFF, (delay >> 8) & 0xFF;
|
||||
buff[3] = FIRMATA_END_SYSEX;
|
||||
serial_write(firmata_dev->serial, buff, 4);
|
||||
mraa_uart_write(firmata_dev->uart, buff, 4);
|
||||
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
@@ -80,9 +79,11 @@ mraa_firmata_send_i2c_read_req(mraa_i2c_context dev, int length)
|
||||
buffer[5] = (length >> 7) & 0x7f;
|
||||
buffer[6] = FIRMATA_END_SYSEX;
|
||||
|
||||
if (serial_write(firmata_dev->serial, buffer, 7) != 7) {
|
||||
mraa_result_t res = mraa_uart_write(firmata_dev->uart, buffer, 7);
|
||||
if (res != MRAA_SUCCESS) {
|
||||
free(buffer);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
mraa_result_print(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// this needs a lock :)
|
||||
@@ -112,9 +113,11 @@ mraa_firmata_send_i2c_read_cont_req(mraa_i2c_context dev, uint8_t command, int l
|
||||
buffer[7] = (length >> 7) & 0x7f;
|
||||
buffer[8] = FIRMATA_END_SYSEX;
|
||||
|
||||
if (serial_write(firmata_dev->serial, buffer, 9) != 9) {
|
||||
mraa_result_t res = mraa_uart_write(firmata_dev->uart, buffer, 9);
|
||||
if (res != MRAA_SUCCESS) {
|
||||
free(buffer);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
mraa_result_print(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// this needs a lock :)
|
||||
@@ -218,7 +221,7 @@ mraa_firmata_i2c_write(mraa_i2c_context dev, const uint8_t* data, int bytesToWri
|
||||
ii = ii+2;
|
||||
}
|
||||
buffer[buffer_size-1] = FIRMATA_END_SYSEX;
|
||||
serial_write(firmata_dev->serial, buffer, buffer_size);
|
||||
mraa_uart_write(firmata_dev->uart, buffer, buffer_size);
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -233,7 +236,7 @@ mraa_firmata_i2c_write_byte(mraa_i2c_context dev, uint8_t data)
|
||||
buffer[4] = data & 0x7F;
|
||||
buffer[5] = (data >> 7) & 0x7F;
|
||||
buffer[6] = FIRMATA_END_SYSEX;
|
||||
serial_write(firmata_dev->serial, buffer, 7);
|
||||
mraa_uart_write(firmata_dev->uart, buffer, 7);
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -250,7 +253,7 @@ mraa_firmata_i2c_write_byte_data(mraa_i2c_context dev, const uint8_t data, const
|
||||
buffer[6] = data & 0x7F;
|
||||
buffer[7] = (data >> 7) & 0x7F;
|
||||
buffer[8] = FIRMATA_END_SYSEX;
|
||||
serial_write(firmata_dev->serial, buffer, 9);
|
||||
mraa_uart_write(firmata_dev->uart, buffer, 9);
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
* Copyright (c) 2015 Jules Dourlens (jdourlens@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "firmata/serial.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
t_serial*
|
||||
serial_new()
|
||||
{
|
||||
t_serial* res;
|
||||
|
||||
res = malloc(sizeof(t_serial));
|
||||
if (!res) {
|
||||
return (NULL);
|
||||
}
|
||||
res->port_is_open = 0;
|
||||
res->baud_rate = 57600;
|
||||
res->tx = 0;
|
||||
res->rx = 0;
|
||||
return (res);
|
||||
}
|
||||
|
||||
int
|
||||
serial_open(t_serial* serial, const char* name)
|
||||
{
|
||||
struct serial_struct kernel_serial_settings;
|
||||
int bits;
|
||||
|
||||
serial->port_fd = open(name, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (serial->port_fd < 0) {
|
||||
if (errno == EACCES) {
|
||||
perror("Unable to access, insufficient permission");
|
||||
} else if (errno == EISDIR) {
|
||||
perror("Unable to open, Object is a directory, not a serial port");
|
||||
} else if (errno == ENODEV || errno == ENXIO) {
|
||||
perror("Unable to open, Serial port hardware not installed");
|
||||
} else if (errno == ENOENT) {
|
||||
perror("Unable to open, Device name does not exist");
|
||||
} else {
|
||||
perror("Unable to open: Unknown error.");
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
memset(&(serial->settings), 0, sizeof(struct termios));
|
||||
#if 0
|
||||
if (ioctl(serial->port_fd, TIOCMGET, &bits) < 0) {
|
||||
close(serial->port_fd);
|
||||
perror("Unable to query serial port signals");
|
||||
return (-1);
|
||||
}
|
||||
bits &= ~(TIOCM_DTR | TIOCM_RTS);
|
||||
if (ioctl(serial->port_fd, TIOCMSET, &bits) < 0) {
|
||||
close(serial->port_fd);
|
||||
perror("Unable to control serial port signals");
|
||||
return (-1);
|
||||
}
|
||||
if (tcgetattr(serial->port_fd, &(serial->settings_orig)) != 0) {
|
||||
close(serial->port_fd);
|
||||
perror("Unable to query serial port settings (perhaps not a serial port)");
|
||||
return (-1);
|
||||
}
|
||||
memset(&(serial->settings), 0, sizeof(struct termios));
|
||||
serial->settings.c_iflag = IGNBRK | IGNPAR;
|
||||
serial->settings.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
|
||||
serial_setBaud(serial, serial->baud_rate);
|
||||
if (ioctl(serial->port_fd, TIOCGSERIAL, &kernel_serial_settings) == 0) {
|
||||
kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
|
||||
ioctl(serial->port_fd, TIOCSSERIAL, &kernel_serial_settings);
|
||||
}
|
||||
tcflush(serial->port_fd, TCIFLUSH);
|
||||
#endif
|
||||
serial->port_name = name;
|
||||
serial->port_is_open = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
serial_setBaud(t_serial* serial, int baud)
|
||||
{
|
||||
speed_t spd;
|
||||
switch (baud) {
|
||||
case 230400:
|
||||
spd = B230400;
|
||||
break;
|
||||
case 115200:
|
||||
spd = B115200;
|
||||
break;
|
||||
case 57600:
|
||||
spd = B57600;
|
||||
break;
|
||||
case 38400:
|
||||
spd = B38400;
|
||||
break;
|
||||
case 19200:
|
||||
spd = B19200;
|
||||
break;
|
||||
case 9600:
|
||||
spd = B9600;
|
||||
break;
|
||||
case 4800:
|
||||
spd = B4800;
|
||||
break;
|
||||
case 2400:
|
||||
spd = B2400;
|
||||
break;
|
||||
case 1800:
|
||||
spd = B1800;
|
||||
break;
|
||||
case 1200:
|
||||
spd = B1200;
|
||||
break;
|
||||
case 600:
|
||||
spd = B600;
|
||||
break;
|
||||
case 300:
|
||||
spd = B300;
|
||||
break;
|
||||
case 200:
|
||||
spd = B200;
|
||||
break;
|
||||
case 150:
|
||||
spd = B150;
|
||||
break;
|
||||
case 134:
|
||||
spd = B134;
|
||||
break;
|
||||
case 110:
|
||||
spd = B110;
|
||||
break;
|
||||
case 75:
|
||||
spd = B75;
|
||||
break;
|
||||
case 50:
|
||||
spd = B50;
|
||||
break;
|
||||
#ifdef B460800
|
||||
case 460800:
|
||||
spd = B460800;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B500000
|
||||
case 500000:
|
||||
spd = B500000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B576000
|
||||
case 576000:
|
||||
spd = B576000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B921600
|
||||
case 921600:
|
||||
spd = B921600;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B1000000
|
||||
case 1000000:
|
||||
spd = B1000000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B1152000
|
||||
case 1152000:
|
||||
spd = B1152000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B1500000
|
||||
case 1500000:
|
||||
spd = B1500000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B2000000
|
||||
case 2000000:
|
||||
spd = B2000000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B2500000
|
||||
case 2500000:
|
||||
spd = B2500000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B3000000
|
||||
case 3000000:
|
||||
spd = B3000000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B3500000
|
||||
case 3500000:
|
||||
spd = B3500000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B4000000
|
||||
case 4000000:
|
||||
spd = B4000000;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B7200
|
||||
case 7200:
|
||||
spd = B7200;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B14400
|
||||
case 14400:
|
||||
spd = B14400;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B28800
|
||||
case 28800:
|
||||
spd = B28800;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B76800
|
||||
case 76800:
|
||||
spd = B76800;
|
||||
break;
|
||||
#endif
|
||||
default: {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
cfsetospeed(&(serial->settings), spd);
|
||||
cfsetispeed(&(serial->settings), spd);
|
||||
if (tcsetattr(serial->port_fd, TCSANOW, &(serial->settings)) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
serial_read(t_serial* serial, void* ptr, int count)
|
||||
{
|
||||
int n, bits;
|
||||
|
||||
if (!serial->port_is_open)
|
||||
return (-1);
|
||||
if (count <= 0)
|
||||
return (0);
|
||||
n = read(serial->port_fd, ptr, count);
|
||||
if (n < 0 && (errno == EAGAIN || errno == EINTR))
|
||||
return (0);
|
||||
if (n == 0 && ioctl(serial->port_fd, TIOCMGET, &bits) < 0)
|
||||
return (-99);
|
||||
serial->rx += n;
|
||||
return (n);
|
||||
}
|
||||
|
||||
int
|
||||
serial_write(t_serial* serial, void* ptr, int len)
|
||||
{
|
||||
//printf("Write %d\n", len);
|
||||
write(serial->port_fd, (const char *)ptr, len);
|
||||
return (len);
|
||||
}
|
||||
|
||||
int
|
||||
serial_waitInput(t_serial* serial, int msec)
|
||||
{
|
||||
if (!serial->port_is_open)
|
||||
return -1;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
tv.tv_sec = msec / 1000;
|
||||
tv.tv_usec = (msec % 1000) * 1000;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(serial->port_fd, &rfds);
|
||||
return (select(serial->port_fd + 1, &rfds, NULL, NULL, &tv));
|
||||
}
|
||||
|
||||
int
|
||||
serial_discardInput(t_serial* serial)
|
||||
{
|
||||
if (!serial->port_is_open)
|
||||
return;
|
||||
// does this really work properly (and is it thread safe) on Linux??
|
||||
tcflush(serial->port_fd, TCIFLUSH);
|
||||
}
|
||||
|
||||
void
|
||||
serial_flushOutput(t_serial* serial)
|
||||
{
|
||||
if (!serial->port_is_open)
|
||||
return;
|
||||
tcdrain(serial->port_fd);
|
||||
}
|
||||
|
||||
int
|
||||
serial_setControl(t_serial* serial, int dtr, int rts)
|
||||
{
|
||||
if (!serial->port_is_open)
|
||||
return -1;
|
||||
int bits;
|
||||
if (ioctl(serial->port_fd, TIOCMGET, &bits) < 0)
|
||||
return -1;
|
||||
if (dtr == 1) {
|
||||
bits |= TIOCM_DTR;
|
||||
} else if (dtr == 0) {
|
||||
bits &= ~TIOCM_DTR;
|
||||
}
|
||||
if (rts == 1) {
|
||||
bits |= TIOCM_RTS;
|
||||
} else if (rts == 0) {
|
||||
bits &= ~TIOCM_RTS;
|
||||
}
|
||||
if (ioctl(serial->port_fd, TIOCMSET, &bits) < 0)
|
||||
return -1;
|
||||
;
|
||||
return (0);
|
||||
}
|
||||
Reference in New Issue
Block a user