diff --git a/lib/bus/rs232/FujiBusPacket.cpp b/lib/bus/rs232/FujiBusPacket.cpp index c75aa8836..c8501877a 100644 --- a/lib/bus/rs232/FujiBusPacket.cpp +++ b/lib/bus/rs232/FujiBusPacket.cpp @@ -114,6 +114,9 @@ bool FujiBusPacket::parse(const std::string &input) if (decoded.size() < sizeof(fujibus_header)) return false; hdr = (fujibus_header *) &decoded[0]; + Debug_printv("Header: dev:%02x cmd:%02x len:%d chk:%02x fld:%02x", + hdr->device, hdr->command, hdr->length, hdr->checksum, hdr->fields); + if (hdr->length != decoded.size()) return false; @@ -131,7 +134,8 @@ bool FujiBusPacket::parse(const std::string &input) fieldCount = numFieldsTable[hdr->fields & FUJI_FIELD_COUNT_MASK]; if (fieldCount) { - _fieldSize = fieldSizeTable[fieldCount]; + _fieldSize = fieldSizeTable[hdr->fields & FUJI_FIELD_COUNT_MASK]; + for (idx = 0; idx < fieldCount; idx++) { for (val = jdx = 0; jdx < _fieldSize; jdx++) @@ -161,6 +165,7 @@ std::string FujiBusPacket::serialize() hdr.command = _command; hdr.length = sizeof(hdr); hdr.checksum = 0; + hdr.fields = 0; std::string output(sizeof(hdr), '\0'); diff --git a/lib/bus/rs232/FujiBusPacket.h b/lib/bus/rs232/FujiBusPacket.h index d225ba420..5b04af587 100644 --- a/lib/bus/rs232/FujiBusPacket.h +++ b/lib/bus/rs232/FujiBusPacket.h @@ -42,6 +42,7 @@ class FujiBusPacket fujiDeviceID_t device() { return _device; } fujiCommandID_t command() { return _command; } unsigned int param(unsigned int index) { return _params[index]; } + unsigned int paramCount() { return _params.size(); } std::optional data() const { return _data; } }; diff --git a/lib/bus/rs232/rs232.cpp b/lib/bus/rs232/rs232.cpp index 720d1ab48..fad0039aa 100755 --- a/lib/bus/rs232/rs232.cpp +++ b/lib/bus/rs232/rs232.cpp @@ -97,6 +97,7 @@ void virtualDevice::bus_to_computer(uint8_t *buf, uint16_t len, bool err) len = length Returns checksum */ +#ifdef OBSOLETE uint8_t virtualDevice::bus_to_peripheral(uint8_t *buf, unsigned short len) { // Retrieve data frame from computer @@ -130,13 +131,27 @@ uint8_t virtualDevice::bus_to_peripheral(uint8_t *buf, unsigned short len) return ck_rcv; } +#else +uint8_t virtualDevice::bus_to_peripheral(uint8_t *buf, unsigned short len) +{ + // FIXME - This is a terrible hack to allow devices to continue + // directly read/write the bus instead of upgrading them to work + // with packets. + size_t rlen = SYSTEM_BUS.read(buf, len); + return rs232_checksum(buf, rlen); +} +#endif /* OBSOLETE */ // RS232 NAK void virtualDevice::rs232_nak() { +#ifdef OBSOLETE SYSTEM_BUS.write('N'); SYSTEM_BUS.flushOutput(); Debug_println("NAK!"); +#else + rs232_error(); +#endif /* OBSOLETE */ } // RS232 ACK @@ -165,10 +180,13 @@ void virtualDevice::rs232_complete() // RS232 ERROR void virtualDevice::rs232_error() { - abort(); +#ifdef OBSOLETE fnSystem.delay_microseconds(DELAY_T5); SYSTEM_BUS.write('E'); Debug_println("ERROR!"); +#else + SYSTEM_BUS.sendReplyPacket(_devnum, false, nullptr, 0); +#endif /* OBSOLETE */ } #ifdef OBSOLETE @@ -219,6 +237,12 @@ void systemBus::_rs232_process_cmd() tempFrame->device(), tempFrame->command(), tempFrame->data() ? tempFrame->data()->size() : -1); + // FIXME - This is a terrible hack to allow devices to continue + // directly read/write the bus instead of upgrading them to work + // with packets. + _lastPacketReceived = tempFrame.get(); + _lastReadPosition = 0; + if (tempFrame->device() == FUJI_DEVICEID_DISK && _fujiDev != nullptr && _fujiDev->boot_config) { @@ -500,8 +524,20 @@ void systemBus::sendReplyPacket(fujiDeviceID_t source, bool ack, void *data, siz /* Convert direct bus access into bus packets? */ size_t systemBus::read(void *buffer, size_t length) { - abort(); - return _port->read(buffer, length); + // FIXME - This is a terrible hack to allow devices to continue + // directly read/write the bus instead of upgrading them to work + // with packets. + // Assuming 'data()' returns the optional: + auto optional_data = _lastPacketReceived->data(); + + if (!optional_data.has_value()) + return 0; + + size_t avail = optional_data.value().size() - _lastReadPosition; + avail = std::min(avail, (size_t) length); + memcpy(buffer, optional_data.value().data() + _lastReadPosition, avail); + _lastReadPosition += avail; + return avail; } size_t systemBus::read() diff --git a/lib/bus/rs232/rs232.h b/lib/bus/rs232/rs232.h index 8bdcf7f42..1eb72c0e9 100755 --- a/lib/bus/rs232/rs232.h +++ b/lib/bus/rs232/rs232.h @@ -199,6 +199,12 @@ struct rs232_message_t class systemBus { private: + // FIXME - DO NOT DO CACHE THE LAST PACKET RECEIVED. This is a + // terrible hack to allow devices to continue directly read/write + // the bus instead of upgrading them to work with packets. + FujiBusPacket *_lastPacketReceived; + size_t _lastReadPosition; + std::forward_list _daisyChain; int _command_frame_counter = 0; diff --git a/lib/device/rs232/network.cpp b/lib/device/rs232/network.cpp index 9a748b40e..cb11e1e28 100644 --- a/lib/device/rs232/network.cpp +++ b/lib/device/rs232/network.cpp @@ -246,7 +246,10 @@ void rs232Network::rs232_read(uint16_t length) // And send off to the computer bus_to_computer((uint8_t *)receiveBuffer->data(), length, err); - receiveBuffer->clear(); + + // Remove from receive buffer and shrink. + receiveBuffer->erase(0, length); + receiveBuffer->shrink_to_fit(); } /** @@ -870,7 +873,12 @@ void rs232Network::rs232_process(FujiBusPacket &packet) rs232_write(packet.param(0)); break; case FUJICMD_STATUS: - rs232_status(static_cast(packet.param(0))); + { + FujiStatusReq reqType = STATUS_NETWORK_CONNERR; + if (packet.paramCount() >= 2) + reqType = (FujiStatusReq) packet.param(1); + rs232_status(reqType); + } break; case FUJICMD_PARSE: rs232_ack();