diff --git a/10.02_devices/2_src/dl11w.cpp b/10.02_devices/2_src/dl11w.cpp index 8b5ab16..c2ba016 100644 --- a/10.02_devices/2_src/dl11w.cpp +++ b/10.02_devices/2_src/dl11w.cpp @@ -61,6 +61,8 @@ slu_c::slu_c() : unibusdevice_c() { type_name.value = "slu_c"; log_label = "slu"; + break_enable.value = 1 ; // SW4-1 per default ON + // SLU has 2 Interrupt vectors: base = RCV, base+= XMT set_default_bus_params(SLU_ADDR, SLU_VECTOR, SLU_LEVEL); // base addr, intr-vector, intr level @@ -191,8 +193,12 @@ void slu_c::eval_xcsr_dato_value(void) { bool new_intr = xmt_ready && xmt_intr_enable; if (!old_intr && new_intr) // raising edge interrupt(intr_vector.value + 4, intr_level.value); - if (old_break != xmt_break) - rs232.SetBreak(xmt_break); + if (old_break != xmt_break) { + // re-evaluate break state on bit change + if (break_enable.value) + rs232.SetBreak(xmt_break); + else rs232.SetBreak(0); + } } void slu_c::eval_xbuf_dato_value(void) { @@ -292,10 +298,18 @@ void slu_c::worker_rcv(void) { // 1. poll with frequency > baudrate, to see single bits unsigned poll_periods_us = 1000000 / baudrate.value; + /* Receiver not time critical? UARTS are buffering + So if thread is swapped out and back a burst of characters appear. + -> Wait after each character for transfer time before polling + RS232 again. + */ + + // worker_init_realtime_priority(rt_device); + while (!workers_terminate) { timeout.wait_us(poll_periods_us); // "query - // rcv_active: can only be set by polling the UART inpit GPIiO pin? + // rcv_active: can only be set by polling the UART input GPIO pin? // at the moments, it is onyl sen on maintenance loopback xmt /* read serial data, if any */ if (rs232.PollComport((unsigned char*) buffer, 1)) { @@ -316,7 +330,6 @@ void slu_c::worker_rcv(void) { n = rs232.PollComport((unsigned char*) buffer, 1); assert(n); // next char after 0xff 0 seq is data" rcv_buffer = buffer[0]; - rcv_done = 1; } else if (buffer[0] == 0xff) { // enocoded 0xff rcv_buffer = 0xff; } else { @@ -327,6 +340,7 @@ void slu_c::worker_rcv(void) { // received non escaped data byte rcv_buffer = buffer[0]; rcv_done = 1; + rcv_active = 0 ; set_rbuf_dati_value(); set_rcsr_dati_value(); // INTR! pthread_mutex_unlock(&on_after_rcv_register_access_mutex); // signal changes atomic against UNIBUS accesses @@ -336,7 +350,12 @@ void slu_c::worker_rcv(void) { void slu_c::worker_xmt(void) { timeout_c timeout; + assert(!pthread_mutex_lock(&on_after_register_access_mutex)); + + // Transmitter not time critical + // worker_init_realtime_priority(rt_device); + while (!workers_terminate) { // 1. wait for xmt signal int res = pthread_cond_wait(&on_after_xmt_register_access_cond, &on_after_xmt_register_access_mutex); diff --git a/10.02_devices/2_src/dl11w.hpp b/10.02_devices/2_src/dl11w.hpp index 42cd0ff..c3053f2 100644 --- a/10.02_devices/2_src/dl11w.hpp +++ b/10.02_devices/2_src/dl11w.hpp @@ -65,23 +65,23 @@ using namespace std; #define BUFLEN 32 // register bit definitions -#define RCSR_RCVR_ACT 004000 -#define RCSR_RCVR_DONE 000200 -#define RCSR_RCVR_INT_ENB 000100 -#define RCSR_RDR_ENB 000001 +#define RCSR_RCVR_ACT 0004000 +#define RCSR_RCVR_DONE 0000200 +#define RCSR_RCVR_INT_ENB 0000100 +#define RCSR_RDR_ENB 0000001 -#define RBUF_ERROR (1 << 15) -#define RBUF_OR_ERR (1 << 14) -#define RBUF_FR_ERR (1 << 13) -#define RBUF_P_ERR (1 << 12) +#define RBUF_ERROR 0100000 +#define RBUF_OR_ERR 0040000 +#define RBUF_FR_ERR 0020000 +#define RBUF_P_ERR 0010000 -#define XCSR_XMIT_RDY 000200 -#define XCSR_XMIT_INT_ENB 000100 -#define XCSR_MAINT 000004 -#define XCSR_BREAK 000001 +#define XCSR_XMIT_RDY 0000200 +#define XCSR_XMIT_INT_ENB 0000100 +#define XCSR_MAINT 0000004 +#define XCSR_BREAK 0000001 -#define LKS_INT_ENB 000100 -#define LKS_INT_MON 000200 +#define LKS_INT_ENB 0000100 +#define LKS_INT_MON 0000200 // background task sleep times #define SLU_MSRATE_MS 10 @@ -154,7 +154,7 @@ public: "Mode: 8N1, 7E1, ... "); parameter_bool_c break_enable = parameter_bool_c(this, "break", "b", /*readonly*/false, - "Enable BREAK transmission"); + "Enable BREAK transmission (M7856 SW4-1)"); #ifdef USED // @David: duplicating device registers as parameters is not necessary ... diff --git a/10.02_devices/2_src/rs232.cpp b/10.02_devices/2_src/rs232.cpp index 2d5c71b..76c13ba 100644 --- a/10.02_devices/2_src/rs232.cpp +++ b/10.02_devices/2_src/rs232.cpp @@ -25,8 +25,8 @@ *************************************************************************** */ -/* 2019, June: made C++, Joerg Hoppe */ -/* Last revision: November 22, 2017 */ +/* 2019, June: made C++, added parity/frame/BREAK option, Joerg Hoppe */ +/* Last revision Teunis van Beelen: November 22, 2017 */ /* For more info and how to use this library, visit: http://www.teuniz.net/RS-232/ */ @@ -227,7 +227,7 @@ int rs232_c::OpenComport(const char *devname, int baudrate, const char *mode, */ int iflag; if (par_and_break) - iflag = IGNBRK | PARMRK | INPCK; + iflag = PARMRK | INPCK; else iflag = ipar; @@ -263,8 +263,8 @@ int rs232_c::OpenComport(const char *devname, int baudrate, const char *mode, new_port_settings.c_iflag = iflag; new_port_settings.c_oflag = 0; new_port_settings.c_lflag = 0; - new_port_settings.c_cc[VMIN] = 0; /* block untill n bytes are received */ - new_port_settings.c_cc[VTIME] = 0; /* block untill a timer expires (n * 100 mSec.) */ + new_port_settings.c_cc[VMIN] = 0; /* block until n bytes are received */ + new_port_settings.c_cc[VTIME] = 0; /* block until a timer expires (n * 100 mSec.) */ cfsetispeed(&new_port_settings, baudr); cfsetospeed(&new_port_settings, baudr); @@ -340,7 +340,7 @@ int rs232_c::SendBuf(unsigned char *buf, int size) { // put byte in to rcv queue void rs232_c::LoopbackByte(unsigned char byte) { - if (ioctl(Cport, TIOCSTI, byte) == -1) { + if (ioctl(Cport, TIOCSTI, &byte) == -1) { perror("unable to insert byte into input queue"); } }