1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-11 08:30:55 +00:00

Adds service requests. The microcontroller now appears to consume keyboard events.

This commit is contained in:
Thomas Harte 2021-02-15 20:33:10 -05:00
parent 2a45e7a8d4
commit e16d5f33d1
5 changed files with 40 additions and 7 deletions

View File

@ -50,6 +50,7 @@ void Bus::set_device_output(size_t device_id, bool output) {
device->adb_bus_did_observe_event(Event::Attention); device->adb_bus_did_observe_event(Event::Attention);
} }
shift_register_ = 1; shift_register_ = 1;
start_target_ = 9; // Consume the stop bit before posting the next byte.
phase_ = Phase::AttentionCapture; phase_ = Phase::AttentionCapture;
} else if(low_microseconds < 50.0) { } else if(low_microseconds < 50.0) {
shift(1); shift(1);
@ -73,15 +74,18 @@ void Bus::set_device_output(size_t device_id, bool output) {
void Bus::shift(unsigned int value) { void Bus::shift(unsigned int value) {
shift_register_ = (shift_register_ << 1) | value; shift_register_ = (shift_register_ << 1) | value;
// Trigger a byte whenever a start bit hits bit 8. // Trigger a byte whenever either:
if(shift_register_ & 0x100) { // * a 'start bit' hits bit 8; or
// * if this was a command byte, wait for the stop bit (i.e. the start bit hits 9).
if(shift_register_ & (1 << start_target_)) {
for(auto device: devices_) { for(auto device: devices_) {
device->adb_bus_did_observe_event(Event::Byte, uint8_t(shift_register_)); device->adb_bus_did_observe_event(Event::Byte, uint8_t(shift_register_ >> (start_target_ - 8)));
} }
// Expect a real start bit only if moving from attention capture to packet // Expect a real start bit only if moving from attention capture to packet
// capture. Otherwise adopt an implied start bit. // capture. Otherwise adopt an implied start bit.
shift_register_ = phase_ == Phase::PacketCapture; shift_register_ = phase_ == Phase::PacketCapture;
start_target_ = 8;
phase_ = Phase::PacketCapture; phase_ = Phase::PacketCapture;
} }
} }

View File

@ -151,6 +151,7 @@ class Bus {
double half_cycles_to_microseconds_ = 1.0; double half_cycles_to_microseconds_ = 1.0;
std::vector<Device *> devices_; std::vector<Device *> devices_;
unsigned int shift_register_ = 0; unsigned int shift_register_ = 0;
unsigned int start_target_ = 8;
bool data_level_ = true; bool data_level_ = true;
// ADB addressing supports at most 16 devices but that doesn't include // ADB addressing supports at most 16 devices but that doesn't include

View File

@ -132,6 +132,8 @@ bool Keyboard::set_key_pressed(Key key, bool is_pressed) {
} }
#undef SetModifierBit #undef SetModifierBit
// Ensure service occurs.
post_service_request();
return true; return true;
} }
@ -144,6 +146,7 @@ void Keyboard::clear_all_keys() {
pressed_keys_[key] = false; pressed_keys_[key] = false;
} }
} }
if(!pending_events_.empty()) post_service_request();
// Mark all modifiers as released. // Mark all modifiers as released.
modifiers_ |= 0xfff8; modifiers_ |= 0xfff8;

View File

@ -27,6 +27,18 @@ void ReactiveDevice::post_response(const std::vector<uint8_t> &&response) {
} }
void ReactiveDevice::advance_state(double microseconds, bool current_level) { void ReactiveDevice::advance_state(double microseconds, bool current_level) {
// First test: is a service request desired?
if(phase_ == Phase::ServiceRequestPending) {
microseconds_at_bit_ += microseconds;
if(microseconds_at_bit_ < 240.0) {
bus_.set_device_output(device_id_, false);
} else {
bus_.set_device_output(device_id_, true);
phase_ = Phase::AwaitingAttention;
}
return;
}
// Do nothing if not in the process of posting a response. // Do nothing if not in the process of posting a response.
if(response_.empty()) return; if(response_.empty()) return;
@ -50,10 +62,10 @@ void ReactiveDevice::advance_state(double microseconds, bool current_level) {
// If this is the start of the packet, wait an appropriate stop-to-start time. // If this is the start of the packet, wait an appropriate stop-to-start time.
if(bit_offset_ == -2) { if(bit_offset_ == -2) {
if(microseconds_at_bit_ < 250.0) { if(microseconds_at_bit_ < 150.0) {
return; return;
} }
microseconds_at_bit_ -= 250.0; microseconds_at_bit_ -= 150.0;
++bit_offset_; ++bit_offset_;
} }
@ -115,8 +127,15 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
command_ = decode_command(value); command_ = decode_command(value);
LOG(command_); LOG(command_);
// Don't do anything if this command isn't relevant here. // If this command doesn't apply here, but a service request is requested,
// post a service request.
if(command_.device != Command::AllDevices && command_.device != ((register3_ >> 8) & 0xf)) { if(command_.device != Command::AllDevices && command_.device != ((register3_ >> 8) & 0xf)) {
if(service_desired_) {
service_desired_ = false;
stop_has_begin_ = false;
phase_ = Phase::ServiceRequestPending;
microseconds_at_bit_ = 0.0;
}
return; return;
} }
@ -138,6 +157,7 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
receive_bytes(2); receive_bytes(2);
} }
} else { } else {
service_desired_ = false;
perform_command(command_); perform_command(command_);
} }
break; break;
@ -156,5 +176,5 @@ void ReactiveDevice::reset() {
} }
void ReactiveDevice::post_service_request() { void ReactiveDevice::post_service_request() {
// TODO. service_desired_ = true;
} }

View File

@ -11,6 +11,7 @@
#include "Bus.hpp" #include "Bus.hpp"
#include <atomic>
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
@ -44,14 +45,18 @@ class ReactiveDevice: public Bus::Device {
AwaitingAttention, AwaitingAttention,
AwaitingCommand, AwaitingCommand,
AwaitingContent, AwaitingContent,
ServiceRequestPending,
} phase_ = Phase::AwaitingAttention; } phase_ = Phase::AwaitingAttention;
std::vector<uint8_t> content_; std::vector<uint8_t> content_;
size_t expected_content_size_ = 0; size_t expected_content_size_ = 0;
Command command_; Command command_;
bool stop_has_begin_ = false;
uint16_t register3_; uint16_t register3_;
const uint8_t default_adb_device_id_; const uint8_t default_adb_device_id_;
std::atomic<bool> service_desired_ = false;
void reset(); void reset();
}; };