Commit 38d1cc17 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Some more co_sensor changes to bring block in line with AVR code.

Small fixes to trace code and trace server.
parent 14b64e2b
...@@ -443,8 +443,11 @@ static void *controller_trace_server(void *arg) ...@@ -443,8 +443,11 @@ static void *controller_trace_server(void *arg)
trace_hdl[i].free = 0; trace_hdl[i].free = 0;
break; break;
} }
if (i == nr_trace_hdl) if (i == nr_trace_hdl) {
log_send(LOG_T_ERROR,
"No free trace handlers, closing trace connection");
close(client); close(client);
}
} else { } else {
log_send(LOG_T_ERROR, "accept() failed: %s", log_send(LOG_T_ERROR, "accept() failed: %s",
strerror(errno)); strerror(errno));
......
...@@ -89,7 +89,7 @@ int main(int argc, char **argv) ...@@ -89,7 +89,7 @@ int main(int argc, char **argv)
blocks = controller_block_nr(); blocks = controller_block_nr();
outputs = 0; outputs = 0;
for (i = 0; i < blocks; i++) { for (i = 0; i < blocks; i++) {
outputs += controller_block_get(i)->inputs; outputs += controller_block_get(i)->outputs;
} }
controller_trace_server_start(CTRL_TRACE_PORT, outputs); controller_trace_server_start(CTRL_TRACE_PORT, outputs);
......
...@@ -39,16 +39,23 @@ ...@@ -39,16 +39,23 @@
struct controller_block_private { struct controller_block_private {
float ppm; float ppm;
float r;
uint8_t control;
uint8_t status;
void *data_rx; void *data_rx;
void *data_tx; void *data_tx;
uint8_t address;
struct controller_bus *bus; struct controller_bus *bus;
struct controller_bus_client *client; struct controller_bus_client *client;
}; };
struct rx_packet { struct rx_packet {
uint16_t vdiv; uint16_t ppm;
uint16_t r;
uint8_t status; uint8_t status;
} __packed; } __packed;
...@@ -57,9 +64,15 @@ struct tx_packet { ...@@ -57,9 +64,15 @@ struct tx_packet {
} __packed; } __packed;
#define VESP_SENSOR_CO_CMD_CONTROL 4 #define VESP_SENSOR_CO_CMD_CONTROL 4
#define VESP_SENSOR_CO_CTRL_ENABLE 1 #define VESP_SENSOR_CO_CTRL_ENABLE 1
#define VESP_SENSOR_CO_CTRL_RAW 2 #define VESP_SENSOR_CO_CTRL_RAW 2
#define VESP_SENSOR_CO_CTRL_PREHEAT 4
#define VESP_SENSOR_CO_STAT_TOGGLE 128
#define VESP_SENSOR_CO_EEPROM_T_OFF 2
#define VESP_SENSOR_CO_EEPROM_T_OFF_L 2
#define VESP_SENSOR_CO_EEPROM_T_OFF_H 3
static void calculate(struct controller_block *sensor) static void calculate(struct controller_block *sensor)
{ {
...@@ -68,10 +81,14 @@ static void calculate(struct controller_block *sensor) ...@@ -68,10 +81,14 @@ static void calculate(struct controller_block *sensor)
struct tx_packet *packet_tx = priv->data_tx; struct tx_packet *packet_tx = priv->data_tx;
/* no calibration yet, just a direct conversion */ /* no calibration yet, just a direct conversion */
priv->ppm = be16toh(packet_rx->vdiv); priv->ppm = be16toh(packet_rx->ppm);
priv->r = be16toh(packet_rx->r);
if (priv->status != (packet_rx->status & VESP_SENSOR_CO_STAT_TOGGLE)) {
priv->status = packet_rx->status & VESP_SENSOR_CO_STAT_TOGGLE;
log_send(LOG_T_DEBUG, "Got new ppm data");
}
packet_tx->control = packet_tx->control = priv->control;
VESP_SENSOR_CO_CTRL_ENABLE | VESP_SENSOR_CO_CTRL_RAW;
} }
static void rx_callback(struct controller_block *block, void *data) static void rx_callback(struct controller_block *block, void *data)
...@@ -84,11 +101,66 @@ static void tx_callback(struct controller_block *block, void *data) ...@@ -84,11 +101,66 @@ static void tx_callback(struct controller_block *block, void *data)
block->private->data_tx = data; block->private->data_tx = data;
} }
static int param_set_enable(struct controller_block *block, char *param,
int argc, va_list val)
{
if (va_arg(val, int))
__sync_fetch_and_or(&block->private->control, VESP_SENSOR_CO_CTRL_ENABLE);
else
__sync_fetch_and_and(&block->private->control, ~VESP_SENSOR_CO_CTRL_ENABLE);
return 0;
}
static int param_set_raw(struct controller_block *block, char *param,
int argc, va_list val)
{
if (va_arg(val, int))
__sync_fetch_and_or(&block->private->control, VESP_SENSOR_CO_CTRL_RAW);
else
__sync_fetch_and_and(&block->private->control, ~VESP_SENSOR_CO_CTRL_RAW);
return 0;
}
static int param_set_preheat(struct controller_block *block, char *param,
int argc, va_list val)
{
if (va_arg(val, int))
__sync_fetch_and_or(&block->private->control, VESP_SENSOR_CO_CTRL_PREHEAT);
else
__sync_fetch_and_and(&block->private->control, ~VESP_SENSOR_CO_CTRL_PREHEAT);
return 0;
}
static int param_set_toff(struct controller_block *block, char *param,
int argc, va_list val)
{
double t_off = va_arg(val, double);
uint16_t ms = t_off * 1000;
vesp_command_write_eeprom(block->private->bus,
block->private->address, VESP_SENSOR_CO_EEPROM_T_OFF_L,
ms & 0xff);
vesp_command_write_eeprom(block->private->bus,
block->private->address, VESP_SENSOR_CO_EEPROM_T_OFF_H,
(ms >> 8) & 0xff);
return 0;
}
static struct controller_block_outterm_list outterms[] = { static struct controller_block_outterm_list outterms[] = {
{ "ppm", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, ppm) }, { "ppm", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, ppm) },
{ "r", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, r) },
{ NULL } { NULL }
}; };
static struct controller_block_param_list params[] = {
{ "enable", false, param_set_enable, .args = { "int", NULL } },
{ "preheat", false, param_set_preheat, .args = { "int", NULL } },
{ "raw", false, param_set_raw, .args = { "int", NULL } },
{ "t_off", false, param_set_toff, .args = { "double", NULL } },
{ NULL },
};
static struct controller_block * block_vesp_sensor_co_create(char *name, static struct controller_block * block_vesp_sensor_co_create(char *name,
int argc, va_list ap) int argc, va_list ap)
{ {
...@@ -108,9 +180,10 @@ static struct controller_block * block_vesp_sensor_co_create(char *name, ...@@ -108,9 +180,10 @@ static struct controller_block * block_vesp_sensor_co_create(char *name,
sensor->private->bus = controller_bus_find(busname); sensor->private->bus = controller_bus_find(busname);
if (!sensor->private->bus) if (!sensor->private->bus)
goto err_bus; goto err_bus;
sensor->private->address = address;
//TODO: check device presence while (vesp_command_get_details(sensor->private->bus, address, &vid, &dev)) {
if (vesp_command_get_details(sensor->private->bus, address, &vid, &dev)) {
log_send(LOG_T_ERROR, "%s: Could not get details of device 0x%02x", log_send(LOG_T_ERROR, "%s: Could not get details of device 0x%02x",
name, address); name, address);
goto err_dev; goto err_dev;
...@@ -131,12 +204,16 @@ static struct controller_block * block_vesp_sensor_co_create(char *name, ...@@ -131,12 +204,16 @@ static struct controller_block * block_vesp_sensor_co_create(char *name,
sizeof(struct tx_packet), tx_callback)) sizeof(struct tx_packet), tx_callback))
goto err_bus_output; goto err_bus_output;
if (controller_block_param_list_add(sensor, params))
goto err_params;
if (controller_block_add(sensor)) if (controller_block_add(sensor))
goto err_add; goto err_add;
return sensor; return sensor;
err_add: err_add:
err_params:
err_bus_output: err_bus_output:
err_bus_input: err_bus_input:
err_dev: err_dev:
......
...@@ -69,13 +69,18 @@ static int vesp_tty_fd_recv(struct controller_block *vesp) ...@@ -69,13 +69,18 @@ static int vesp_tty_fd_recv(struct controller_block *vesp)
int fd = priv->fd; int fd = priv->fd;
void *rx_buffer = priv->rx_buffer; void *rx_buffer = priv->rx_buffer;
log_send(LOG_T_DEBUG, "%s: try to receive %zd", vesp->name, priv->rx_size); if (fd < 0)
return -1;
// log_send(LOG_T_DEBUG, "%s: try to receive %zd from fd %d",
// vesp->name, priv->rx_size, fd);
ret = read(fd, rx_buffer, priv->rx_size); ret = read(fd, rx_buffer, priv->rx_size);
if (ret > 0) { if (ret > 0) {
log_send(LOG_T_DEBUG, "received %zd bytes", ret); // log_send(LOG_T_DEBUG, "received %zd bytes", ret);
vesp_input_process(priv->bus, rx_buffer, ret); vesp_input_process(priv->bus, rx_buffer, ret);
} else { } else {
if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { if (ret == 0 ||
(ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK)) {
log_send(LOG_T_ERROR, log_send(LOG_T_ERROR,
"%s: Error reading from device(%zd): %s", "%s: Error reading from device(%zd): %s",
vesp->name, ret, strerror(errno)); vesp->name, ret, strerror(errno));
...@@ -157,13 +162,14 @@ static int vesp_tty_send(struct controller_bus *bus, void *data, size_t size) ...@@ -157,13 +162,14 @@ static int vesp_tty_send(struct controller_bus *bus, void *data, size_t size)
if (fd < 0) if (fd < 0)
goto err; goto err;
log_send(LOG_T_DEBUG, "%s: send %zd bytes", bus->name, size);
ret = write(fd, data, size); ret = write(fd, data, size);
if (ret == size) if (ret == size)
return 0; return 0;
log_send(LOG_T_ERROR, "%s: failed to send %zd bytes: %s", log_send(LOG_T_ERROR, "%s: failed to send %zd bytes: %s",
vesp->name, ret, strerror(errno)); vesp->name, ret, strerror(errno));
close(fd);
priv->fd = -1;
err: err:
return -1; return -1;
} }
...@@ -189,16 +195,17 @@ static int vesp_dev_open(struct controller_block *block) ...@@ -189,16 +195,17 @@ static int vesp_dev_open(struct controller_block *block)
{ {
struct controller_block_private *priv = block->private; struct controller_block_private *priv = block->private;
struct termios tty; struct termios tty;
int fd;
priv->fd = open(priv->devname, O_RDWR | O_NOCTTY | O_NONBLOCK); fd = open(priv->devname, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (priv->fd < 0) { if (fd < 0) {
log_send(LOG_T_ERROR, "%s: Opening VESP device %s failed", log_send(LOG_T_ERROR, "%s: Opening VESP device %s failed",
block->name, priv->devname); block->name, priv->devname);
goto err; goto err;
} }
memset (&tty, 0, sizeof tty); memset (&tty, 0, sizeof tty);
if (tcgetattr (priv->fd, &tty) != 0) { if (tcgetattr (fd, &tty) != 0) {
log_send(LOG_T_ERROR, "%s: tcgetattr(): %s", log_send(LOG_T_ERROR, "%s: tcgetattr(): %s",
block->name, strerror(errno)); block->name, strerror(errno));
goto err; goto err;
...@@ -228,7 +235,7 @@ static int vesp_dev_open(struct controller_block *block) ...@@ -228,7 +235,7 @@ static int vesp_dev_open(struct controller_block *block)
tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS; tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (priv->fd, TCSANOW, &tty) != 0) { if (tcsetattr (fd, TCSANOW, &tty) != 0) {
log_send(LOG_T_DEBUG, "%s: tcsetattr() %s", log_send(LOG_T_DEBUG, "%s: tcsetattr() %s",
block->name, strerror(errno)); block->name, strerror(errno));
goto err; goto err;
...@@ -264,19 +271,20 @@ static int vesp_dev_open(struct controller_block *block) ...@@ -264,19 +271,20 @@ static int vesp_dev_open(struct controller_block *block)
/* Set this flag if you want to receive data even whilst sending data */ /* Set this flag if you want to receive data even whilst sending data */
//rs485conf.flags |= SER_RS485_RX_DURING_TX; //rs485conf.flags |= SER_RS485_RX_DURING_TX;
if (ioctl (priv->fd, TIOCSRS485, &rs485conf) < 0) { if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
log_send(LOG_T_WARNING, "%s: ioctl(TIOCSRS485): %s", log_send(LOG_T_WARNING, "%s: ioctl(%d, TIOCSRS485): %s",
block->name, strerror(errno)); block->name, fd, strerror(errno));
} }
#endif #endif
log_send(LOG_T_INFO, "%s: Opened %s", block->name, priv->devname); log_send(LOG_T_INFO, "%s: Opened %s", block->name, priv->devname);
priv->fd = fd;
return 0; return 0;
err: err:
if (priv->fd >= 0) { if (fd >= 0) {
close(priv->fd); close(fd);
priv->fd = -1; priv->fd = -1;
} }
return -1; return -1;
...@@ -290,11 +298,9 @@ static enum controller_bus_state vesp_tty_poll(struct controller_bus *bus) ...@@ -290,11 +298,9 @@ static enum controller_bus_state vesp_tty_poll(struct controller_bus *bus)
if (fd >= 0) if (fd >= 0)
return CONTROLLER_BUS_STATE_OK; return CONTROLLER_BUS_STATE_OK;
fd = vesp_dev_open(block); if (vesp_dev_open(block))
if (fd < 0)
return CONTROLLER_BUS_STATE_ERROR; return CONTROLLER_BUS_STATE_ERROR;
block->private->fd = fd;
log_send(LOG_T_WARNING, "%s: re-opened %s", block->name, log_send(LOG_T_WARNING, "%s: re-opened %s", block->name,
block->private->devname); block->private->devname);
......
...@@ -226,9 +226,11 @@ int vesp_input_process(struct controller_bus *bus, void *data, size_t size) ...@@ -226,9 +226,11 @@ int vesp_input_process(struct controller_bus *bus, void *data, size_t size)
for (p = 0; p < size; p++) { for (p = 0; p < size; p++) {
uint8_t b = data8[p]; uint8_t b = data8[p];
log_send(LOG_T_DEBUG, "%s: recv %zd: 0x%02x", bus->name, p, b); // log_send(LOG_T_DEBUG, "%s: recv %zd: 0x%02x", bus->name, p, b);
if (b == VESP_PKT_END || priv->rx_cur >= priv->rx_size) { if (b == VESP_PKT_END || priv->rx_cur >= priv->rx_size) {
// log_send(LOG_T_DEBUG, "Got end, %zd bytes, crc: 0x%02x",
// priv->rx_cur, priv->rx_crc);
/* crc must be ok and the packet must have atleast 2 bytes (add + resp) */ /* crc must be ok and the packet must have atleast 2 bytes (add + resp) */
if (!priv->rx_crc && priv->rx_cur > 2) { if (!priv->rx_crc && priv->rx_cur > 2) {
vesp_input_process_pkt(bus, priv->rx_buffer, priv->rx_cur - 1); vesp_input_process_pkt(bus, priv->rx_buffer, priv->rx_cur - 1);
...@@ -251,6 +253,7 @@ int vesp_input_process(struct controller_bus *bus, void *data, size_t size) ...@@ -251,6 +253,7 @@ int vesp_input_process(struct controller_bus *bus, void *data, size_t size)
priv->rx_esc = false; priv->rx_esc = false;
priv->rx_buffer[priv->rx_cur] = b; priv->rx_buffer[priv->rx_cur] = b;
priv->rx_crc = vesp_crc8(priv->rx_crc, b); priv->rx_crc = vesp_crc8(priv->rx_crc, b);
priv->rx_cur++;
} }
} }
} }
...@@ -301,9 +304,9 @@ int vesp_output_frame(struct controller_bus *bus, void *data, size_t size) ...@@ -301,9 +304,9 @@ int vesp_output_frame(struct controller_bus *bus, void *data, size_t size)
} }
frame[pf++] = VESP_PKT_END; frame[pf++] = VESP_PKT_END;
for (pp = 0; pp < pf; pp++) { // for (pp = 0; pp < pf; pp++) {
log_send(LOG_T_DEBUG, "%s: send[%zd]: 0x%02x", bus->name, pp, frame[pp]); // log_send(LOG_T_DEBUG, "%s: send[%zd]: 0x%02x", bus->name, pp, frame[pp]);
} // }
return priv->send(bus, frame, pf); return priv->send(bus, frame, pf);
} }
......
...@@ -20,6 +20,11 @@ links { ...@@ -20,6 +20,11 @@ links {
params { params {
# { "operational", "value", 4, (int) { true, true, true, true } } # { "operational", "value", 4, (int) { true, true, true, true } }
{ "co_sensor", "enable", true }
{ "co_sensor", "raw", true }
{ "co_sensor", "preheat", false }
{ "co_sensor", "t_off", 0.1 }
# { "co_sensor_ppm", "value", 4, # { "co_sensor_ppm", "value", 4,
# (float){ 0.0, 0.0, 0.0, 0.0 }, # (float){ 0.0, 0.0, 0.0, 0.0 },
# (float){ 0.0, 0.0, 0.0, 0.0 } # (float){ 0.0, 0.0, 0.0, 0.0 }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment