mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
Extend to allow full-[byte/word/dword] writes, in LSB or MSB order.
This commit is contained in:
parent
471e13efbc
commit
f102d8a4b4
@ -8,6 +8,8 @@
|
||||
|
||||
#include "Line.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
using namespace Serial;
|
||||
|
||||
void Line::set_writer_clock_rate(HalfCycles clock_rate) {
|
||||
@ -70,7 +72,7 @@ void Line::write(bool level) {
|
||||
}
|
||||
}
|
||||
|
||||
void Line::write(HalfCycles cycles, int count, int levels) {
|
||||
template <bool lsb_first, typename IntT> void Line::write_internal(HalfCycles cycles, int count, IntT levels) {
|
||||
remaining_delays_ += count * cycles.as_integral();
|
||||
|
||||
auto event = events_.size();
|
||||
@ -78,12 +80,38 @@ void Line::write(HalfCycles cycles, int count, int levels) {
|
||||
while(count--) {
|
||||
events_[event].type = Event::Delay;
|
||||
events_[event].delay = int(cycles.as_integral());
|
||||
events_[event+1].type = (levels&1) ? Event::SetHigh : Event::SetLow;
|
||||
levels >>= 1;
|
||||
IntT bit;
|
||||
if constexpr (lsb_first) {
|
||||
bit = levels & 1;
|
||||
levels >>= 1;
|
||||
} else {
|
||||
constexpr auto top_bit = std::numeric_limits<IntT>::max() - (std::numeric_limits<IntT>::max() >> 1);
|
||||
bit = levels & top_bit;
|
||||
levels <<= 1;
|
||||
}
|
||||
|
||||
events_[event+1].type = bit ? Event::SetHigh : Event::SetLow;
|
||||
event += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void Line::write(HalfCycles cycles, int count, int levels) {
|
||||
write_internal<true, int>(cycles, count, levels);
|
||||
}
|
||||
|
||||
template <bool lsb_first, typename IntT> void Line::write(HalfCycles cycles, IntT value) {
|
||||
write_internal<lsb_first, IntT>(cycles, 8 * sizeof(IntT), value);
|
||||
}
|
||||
|
||||
template void Line::write<true, uint8_t>(HalfCycles, uint8_t);
|
||||
template void Line::write<false, uint8_t>(HalfCycles, uint8_t);
|
||||
template void Line::write<true, uint16_t>(HalfCycles, uint16_t);
|
||||
template void Line::write<false, uint16_t>(HalfCycles, uint16_t);
|
||||
template void Line::write<true, uint32_t>(HalfCycles, uint32_t);
|
||||
template void Line::write<false, uint32_t>(HalfCycles, uint32_t);
|
||||
template void Line::write<true, uint64_t>(HalfCycles, uint64_t);
|
||||
template void Line::write<false, uint64_t>(HalfCycles, uint64_t);
|
||||
|
||||
void Line::reset_writing() {
|
||||
remaining_delays_ = 0;
|
||||
events_.clear();
|
||||
|
@ -44,6 +44,10 @@ class Line {
|
||||
/// relative to the writer's clock rate.
|
||||
void write(HalfCycles cycles, int count, int levels);
|
||||
|
||||
/// Enqueus every bit from @c value as per the rules of write(HalfCycles, int, int),
|
||||
/// either in LSB or MSB order as per the @c lsb_first template flag.
|
||||
template <bool lsb_first, typename IntT> void write(HalfCycles cycles, IntT value);
|
||||
|
||||
/// @returns the number of cycles until currently enqueued write data is exhausted.
|
||||
forceinline HalfCycles write_data_time_remaining() const {
|
||||
return HalfCycles(remaining_delays_);
|
||||
@ -98,6 +102,9 @@ class Line {
|
||||
|
||||
void update_delegate(bool level);
|
||||
HalfCycles::IntType minimum_write_cycles_for_read_delegate_bit();
|
||||
|
||||
template <bool lsb_first, typename IntT> void
|
||||
write_internal(HalfCycles, int, IntT);
|
||||
};
|
||||
|
||||
/*!
|
||||
|
Loading…
Reference in New Issue
Block a user