DC11: I/O to "Stream"-device (serial port on Arduino)

This commit is contained in:
folkert van heusden 2024-05-08 09:33:05 +02:00
parent 476ead28bc
commit 35068a34ee
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
2 changed files with 66 additions and 15 deletions

View file

@ -1,6 +1,9 @@
// (C) 2024 by Folkert van Heusden // (C) 2024 by Folkert van Heusden
// Released under MIT license // Released under MIT license
#if defined(ESP32)
#include <Arduino.h>
#endif
#if defined(ESP32) #if defined(ESP32)
#include <lwip/sockets.h> #include <lwip/sockets.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -49,6 +52,13 @@ dc11::~dc11()
} }
delete [] pfds; delete [] pfds;
#if defined(ESP32)
if (serial_th) {
serial_th->join();
delete serial_th;
}
#endif
} }
void dc11::trigger_interrupt(const int line_nr, const bool is_tx) void dc11::trigger_interrupt(const int line_nr, const bool is_tx)
@ -63,13 +73,15 @@ void dc11::operator()()
DOLOG(info, true, "DC11 thread started"); DOLOG(info, true, "DC11 thread started");
for(int i=0; i<dc11_n_lines; i++) { for(int i=0; i<dc11_n_lines; i++) {
#if defined(ESP32)
if (i == 3) // uggly hack
break;
#endif
// client session // client session
pfds[dc11_n_lines + i].fd = INVALID_SOCKET; pfds[dc11_n_lines + i].fd = INVALID_SOCKET;
pfds[dc11_n_lines + i].events = POLLIN; pfds[dc11_n_lines + i].events = POLLIN;
#if defined(ESP32)
if (i == 3) { // prevent accept() on this socket
pfds[i].fd = INVALID_SOCKET;
continue;
}
#endif
// listen on port // listen on port
int port = base_port + i + 1; int port = base_port + i + 1;
@ -188,6 +200,38 @@ void dc11::operator()()
} }
} }
#if defined(ESP32)
void dc11::set_serial(Stream *const s)
{
if (serial_th) {
DOLOG(info, true, "DC11: serial port already configured");
return;
}
this->s = s;
serial_th = new std::thread(&dc11::serial_handler, this);
}
void dc11::serial_handler()
{
while(!stop_flag) {
yield();
if (s->available() == 0)
continue;
// 3 is reserved for a serial port
recv_buffers[3].push_back(s->read());
registers[3 * 4 + 0] |= 128; // DONE: bit 7
if (is_rx_interrupt_enabled(3))
trigger_interrupt(3, false);
}
}
#endif
void dc11::reset() void dc11::reset()
{ {
} }
@ -310,6 +354,13 @@ void dc11::write_word(const uint16_t addr, const uint16_t v)
else else
TRACE("DC11: transmit %c on line %d", c, line_nr); TRACE("DC11: transmit %c on line %d", c, line_nr);
#if defined(ESP32)
if (line_nr == 3) {
if (s != nullptr)
s->write(c);
return;
}
#endif
SOCKET fd = pfds[dc11_n_lines + line_nr].fd; SOCKET fd = pfds[dc11_n_lines + line_nr].fd;
if (fd != INVALID_SOCKET && write(fd, &c, 1) != 1) { if (fd != INVALID_SOCKET && write(fd, &c, 1) != 1) {

6
dc11.h
View file

@ -2,9 +2,6 @@
// Released under MIT license // Released under MIT license
#pragma once #pragma once
#if defined(ESP32)
#include <Arduino.h>
#endif
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <cstdint> #include <cstdint>
@ -27,6 +24,7 @@
#define DC11_BASE DC11_RCSR #define DC11_BASE DC11_RCSR
#define DC11_END (DC11_BASE + (4 * 4 + 1) * 2) // 4 interfaces, + 2 to point behind it #define DC11_END (DC11_BASE + (4 * 4 + 1) * 2) // 4 interfaces, + 2 to point behind it
class Stream;
class bus; class bus;
struct pollfd; struct pollfd;
@ -52,6 +50,7 @@ private:
std::mutex input_lock[dc11_n_lines]; std::mutex input_lock[dc11_n_lines];
#if defined(ESP32) #if defined(ESP32)
Stream *s { nullptr }; Stream *s { nullptr };
std::thread *serial_th { nullptr };
#endif #endif
void trigger_interrupt(const int line_nr, const bool is_tx); void trigger_interrupt(const int line_nr, const bool is_tx);
@ -70,6 +69,7 @@ public:
void reset(); void reset();
#if defined(ESP32) #if defined(ESP32)
void set_serial(Stream *const s); void set_serial(Stream *const s);
void serial_handler();
#endif #endif
uint8_t read_byte(const uint16_t addr); uint8_t read_byte(const uint16_t addr);